我有最奇怪的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?
答案 0 :(得分:4)
参考:http://php.net/manual/en/mysqlinfo.concepts.buffering.php
PDO默认使用“缓冲查询”。
这意味着查询结果会立即从中传输 然后将MySQL Server中的PHP Server保存在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;
}
}
?>