我看到了建议使用光标解决我的原始问题的文章。后加入PDO驱动程序是否已经在内部使用光标?如果需要编写自己的SQL来创建光标,我愿意,但是我宁愿编写最简单的代码(但不要简单!)。
如果每个迭代for for for foreach call fetch()还是它很聪明,一次又一行,例如500,保存带宽? (这可能意味着它在内部使用光标。) 我看到了一篇文章,该文章将语句句柄包装在实现迭代界面的类中。鉴于PDO语句的处理已经这样做,这不是冗余吗?还是我想念什么?
$ sth = $ dbh->准备($ sql);
我发现,如果我这样做,它没有记忆或速度差异:
$sth = $dbh->prepare($sql, array( PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY ) );
欢迎有关方法和解决此问题的其他方法的一般评论。
。
明显不使用光标。黑匣子测试:
PDO::CURSOR_FWDONLY
(1)默认值 - 永远使用:
$con = new \PDO('dsn');
// you'll get "NO ACTIVE TRANSACTION" otherwise
$con->beginTransaction();
$sql = 'select * from largetable';
(2)fwdonly-永远花:
$stmt = $con->prepare($sql);
$stmt->execute();
print_r($stmt->fetch());
$stmt = $con->prepare($sql, array(\PDO::ATTR_CURSOR => \PDO::CURSOR_FWDONLY));
$stmt->execute();
print_r($stmt->fetch());
so,使用光标的唯一方法是使用滚动,至少在PHP 5.4.23中。
内部光标: PHP具有与光标明确打交道的内部代码(如jon的答案指向),
但是,我没有设法使驱动程序输入此代码(使用$stmt = $con->prepare($sql, array(\PDO::ATTR_CURSOR => \PDO::CURSOR_SCROLL));
$stmt->execute();
print_r($stmt->fetch());
)。也许是因为我专注于setAttribute()
约翰·史密斯(Johnsmith)的回答。
CURSOR_FWONLY
和网络:
在网络方面,fetch()
fetchAll()
fetch()
将从网络缓冲区的遗迹开始(它甚至可能在其中找到一排,因此立即返回),依此类推。
…但这是理论上的,在记忆方面,有一个真正的问题迭代在声明中需要专用处理(
getline()
)ivil php 8's:一个人无法互换地接受一个或迭代的数组,他们需要具有特定的循环,或包裹成一个自制的
fetch()
。
没有什么可以添加到约翰史密斯的回答
while(($row = $stmt->fetch()))
直到php8.4之前,不是真正的
getIterator()
在历史上,
PDOStatement
做了一个内部Iterator
,等待服务器已经完成了整个置换式(并完全延误),然后再提供第一行;fetch()
报告。唯一的安慰是也许这是原始的数据记忆,尚未转换为PHP数组,所以有点节俭。
但这绝对没有用,它的名字给人一种虚假的信心。
PHP8.4引入了一个(在PDO上或语句上)ALLASS
fetch()
aallows
fetch()
以按需工作,逐行工作,而无需将结果存储在mem中;一直以来应该拥有的。
仍然存在副作用(例如,在弹出结果时可以防止内部效果),但在转储到CSV方案中完全可以使用。