5

我有一个最奇怪的 PHP PDO 问题,希望你们能帮我解决。

如果我设置$checkLimit为 50000,则查询工作正常。但是,如果我将其设置为 50k 以上的任何值,它不会返回任何结果 - 也不会投射任何错误消息(我已经使用$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING).

$sql = "
   SELECT d_domain_name AS domainName, d_domain_id AS domainID
   FROM domains
   ORDER BY d_domain_name_length ASC, d_domain_name ASC
   LIMIT :checkLimit
";
$stmt = $db->prepare($sql);
$stmt->bindValue(':checkLimit', intval($checkLimit), PDO::PARAM_INT);
$stmt->execute();
$results = $stmt->fetchAll();
foreach ($results as $result) {
 // 50k moments of magic
}

如果我在 PHP 之外运行查询,它可以使用任何限制(甚至 500k,大约需要 3 分钟)。

我尝试更改$results = $stmt->fetchAll()while ($result = $stmt->fetch()) {}以尝试节省内存,但不幸的是,这并没有做任何事情。

谁能告诉我我在这里做错了什么?我错过了什么?为什么我不能超过50k?

4

1 回答 1

4

参考: http: //php.net/manual/en/mysqlinfo.concepts.buffering.php

PDO 默认使用“缓冲查询”。

这意味着查询结果会立即从 MySQL 服务器传输到 PHP,然后保存在 PHP 进程的内存中。.... 缓冲模式的缺点是较大的结果集可能需要相当多的内存。……

遵循这些特征缓冲查询应该用于您只期望有限的结果集或需要在读取所有行之前知道返回行的数量的情况。当您期望更大的结果时,应使用无缓冲模式。

50k 是一个很大的结果集。您可以尝试让 pdo 使用无缓冲模式一次获取一行吗?这是从参考中复制的示例。第二行设置无缓冲模式。

<?php
$pdo = new PDO("mysql:host=localhost;dbname=world", 'my_user', 'my_pass');
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);

$uresult = $pdo->query("SELECT Name FROM City");
if ($uresult) {
   while ($row = $uresult->fetch(PDO::FETCH_ASSOC)) {
       echo $row['Name'] . PHP_EOL;
   }
}
?>
于 2013-03-23T05:07:05.080 回答