【发布时间】:2011-10-17 05:30:08
【问题描述】:
我在处理从大约 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 meg 的内存。我已经计算出通过将“SELECT *”替换为“SELECT home, away”可以将内存减少大约 6 倍,但是我认为即使这种用法也非常高,而且表格只会变得更大。
是否有我遗漏的设置,或者我应该注意 PDO 中的某些限制?如果 PDO 不能支持这一点,我很高兴摆脱 PDO 以支持 mysqli,所以如果这是我唯一的选择,我将如何使用 mysqli 来执行此操作?
【问题讨论】:
-
这正是 noSQL 和 MapReduce 的用例。由于 map 和 reduce 函数将在您的数据“附近”执行。你可以试试 MongoDB 或 CouchBase(或者 Hadoop 为什么不试试,其实很简单)。