【发布时间】:2014-06-28 02:32:06
【问题描述】:
经过一些研究,我对生成器(更一般地说,迭代器)的想法很满意,因为这些任务通常会将结果缓冲到数组中,因为内存使用量是 O(1) 而不是 O(n) .
所以我打算使用生成器来处理通过 mysqli 查询的数据库结果。关于这种方法,我有 2 个问题无法找到答案,希望社区能给我一些创造性的解决方案:
如果消费代码选择不完全迭代结果,有没有办法释放生成器打开的资源?使用 Iterator 类,可以在 __desctruct 方法中执行此操作。但是,从我的测试来看,如果生成器不能自然结束,它将根本不会执行迭代序列之后的代码。我正在寻找解决方法,以防止必须创建 Iterator 子类。请参阅下面的代码。
使用生成器或迭代器是否对数据库结果有任何好处?我的一些窥探似乎表明 mysqli 可能无论如何都会将结果集加载到内存中(MYSQLI_STORE_RESULT),从而破坏了迭代器的目的。如果结果没有缓冲,我很好奇是否可以在同时迭代(获取)结果集的同时执行多个查询(想想嵌套循环,您正在迭代一组项目,然后查询每个项目的子项目父母)。这似乎数据库游标可能会在整个迭代过程中锁定。
示例
下面是我所说的清理的简化。根据我的测试,只有迭代整个结果时才会释放结果。如果消费循环中出现异常或中断,则结果永远不会被释放。也许是我想太多了,垃圾收集器足够好?
function query($mysqli, $sql){
$result = $mysqli->query($sql);
foreach($result as $row){
yield $row;
}
$result->free(); //Never reached if break, exception, take first n rows, etc.
}
tl;dr 我只是好奇如何释放生成器使用的资源,以及随后用于数据库访问的生成器是否真的节省了任何东西,或者结果是否被缓冲了
更新
这里 (http://www.php.net/manual/en/mysqlinfo.concepts.buffering.php) 看起来像默认情况下 PHP 缓冲查询,可能违背了生成器的目的。虽然可以说只缓冲一个数组比创建一个缓冲数组的副本然后拥有两个缓冲集更好。
我正在寻找对此事有经验的人来权衡。感谢您的想法!
【问题讨论】: