我有一个奇怪的时间处理从大约30,000行的表中选择.
似乎我的脚本使用了大量的内存,因为这是一个简单的,仅向前遍历查询结果的内容.
请注意,这个例子是一个有点人为的,绝对的最小例子,它与真实代码几乎没有相似之处,它不能用简单的数据库聚合代替.它旨在说明每次迭代时不需要保留每一行的要点.
<?php
$pdo = new PDO('mysql:host=127.0.0.1', 'foo', 'bar', array(
    PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION,
));
$stmt = $pdo->prepare('SELECT * FROM round');
$stmt->execute();
function do_stuff($row) {}
$c = 0;
while ($row = $stmt->fetch()) {
    // do something with the object that doesn't involve keeping 
    // it around and can't be done in SQL
    do_stuff($row);
    $row = null;
    ++$c;
}
var_dump($c);
var_dump(memory_get_usage());
var_dump(memory_get_peak_usage());
这输出:
int(39508)
int(43005064)
int(43018120)
我不明白为什么在任何时候几乎不需要保存任何数据时使用40兆内存.我已经解决了我可以通过用"SELECT home,away"替换"SELECT*"来减少大约6倍的内存,但是我认为即使这种用法非常高,而且表只会变得更大.
是否有我缺少的设置,或者我应该注意PDO的某些限制?我很高兴摆脱PDO而不支持mysqli,如果它不能支持这个,那么如果这是我唯一的选择,我将如何使用mysqli执行此操作呢?
Sha*_*obe 57
创建连接后,您需要设置PDO::MYSQL_ATTR_USE_BUFFERED_QUERY为false:
<?php
$pdo = new PDO('mysql:host=127.0.0.1', 'foo', 'bar', array(
    PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION,
));
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
// snip
var_dump(memory_get_usage());
var_dump(memory_get_peak_usage());
这输出:
int(39508)
int(653920)
int(668136)
无论结果大小如何,内存使用量仍然非常静态.