Current Location: Home> Latest Articles> How to avoid duplicate queries when multiple calls to PDOStatement::fetchObject

How to avoid duplicate queries when multiple calls to PDOStatement::fetchObject

gitbox 2025-05-12

In PHP, PDOStatement::fetchObject is a commonly used method to obtain data from a database. Usually, we use this method to get data row by row or batch by batch. However, in some cases, duplicate queries may occur when we execute queries multiple times, resulting in performance issues. To avoid this, we can optimize the query through different methods to ensure that the data that has been queryed is not repeated.

This article will use examples to illustrate how to avoid duplicate queries when using PDOStatement::fetchObject to fetch data multiple times, and provide some commonly used optimization strategies.

1. What is PDOStatement::fetchObject ?

First, it is very important to understand how the PDOStatement::fetchObject method works. This method returns the object representation of the current result row, and moves the pointer down to the next row each time it is called. Typical usages are as follows:

 <?php
$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'username', 'password');
$stmt = $pdo->prepare("SELECT id, name FROM users");
$stmt->execute();

while ($user = $stmt->fetchObject()) {
    echo $user->id . ' - ' . $user->name . "<br>";
}
?>

The above code executes the query and outputs data line by line. Each time fetchObject() is called, a request will be initiated to the database.

2. Repeat query questions

Suppose you have a more complex query logic that may call fetchObject in multiple places, which may cause duplicate queries. For example, some user data needs to be retrieved in multiple pages or operations, and if the database is requeried each time, the performance will be affected.

3. Use the caching mechanism

One way to optimize is to use cache to avoid duplicate queries. When we query data for the first time, we can cache the results to memory (for example through cache mechanisms such as APCu or Memcached in PHP). In subsequent requests, data can be retrieved directly from the cache without querying the database again.

For example, a simple implementation using APCu cache:

 <?php
$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'username', 'password');
$stmt = $pdo->prepare("SELECT id, name FROM users");
$stmt->execute();

while ($user = $stmt->fetchObject()) {
    // use APCu cache
    $cacheKey = 'user_' . $user->id;
    if (!apcu_exists($cacheKey)) {
        apcu_store($cacheKey, $user);
    }
    $cachedUser = apcu_fetch($cacheKey);
    echo $cachedUser->id . ' - ' . $cachedUser->name . "<br>";
}
?>

In this example, we use APCu to cache each user object. If the data has been cached, use the cached data directly instead of re-querying from the database.

4. Use pagination query to reduce duplicate data loading

If your query returns a large amount of data, another optimization strategy is to use pagination queries. By loading the query results in batches, it can avoid loading too much data at once, resulting in multiple queries.

Here is an example of a pagination query:

 <?php
$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'username', 'password');
$limit = 10; // Each query10Data
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$offset = ($page - 1) * $limit;

$stmt = $pdo->prepare("SELECT id, name FROM users LIMIT :limit OFFSET :offset");
$stmt->bindParam(':limit', $limit, PDO::PARAM_INT);
$stmt->bindParam(':offset', $offset, PDO::PARAM_INT);
$stmt->execute();

while ($user = $stmt->fetchObject()) {
    echo $user->id . ' - ' . $user->name . "<br>";
}
?>

In this example, LIMIT and OFFSET are used for pagination queries, ensuring that only part of the required data is loaded at a time, rather than all data loading at once.

5. Avoid executing the same query multiple times

If you need the same query result multiple times in the same script, consider cache the query result into a variable instead of calling fetchObject multiple times. For example:

 <?php
$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'username', 'password');
$stmt = $pdo->prepare("SELECT id, name FROM users");
$stmt->execute();

$users = [];
while ($user = $stmt->fetchObject()) {
    $users[] = $user;
}

// 后续use已经加载的用户数据,Without querying again
foreach ($users as $user) {
    echo $user->id . ' - ' . $user->name . "<br>";
}
?>

Here, we store the query results in the $users array to avoid repeated querying of the database in subsequent code.

6. Other optimization strategies

In addition to caching and paging, the following are some commonly used optimization strategies:

  • Avoid using SELECT * : Try to select only the fields you need to reduce the transfer of data.

  • Batch query : Try to query multiple records at once, rather than querying them one by one.

  • Use indexes : Ensure that the relevant fields in the database table have appropriate indexes to improve query efficiency.