我有一个庞大的mysql数据库(几个100000条记录)。我使用PDO来访问它。我需要以大约100条记录为单位获取数据。 PDO :: fetchall会导致太多记录并耗尽PC内存。 PDO :: fetch只给我一条记录。
有没有办法请求下一个n(比方说100)记录?
由于
答案 0 :(得分:0)
PDO :: fetch只给我一条记录。
您始终可以通过另一个调用来获取另一条记录。依此类推,直到获取所有记录,就像每个例子中所示:
while ($row = $stmt->fetch() {
print $row[0];
}
请注意,您还可以将PDO::MYSQL_ATTR_USE_BUFFERED_QUERY设置为false以减少内存消耗
答案 1 :(得分:0)
MySQL客户端 - 服务器协议允许从单个响应数据包中的语句的结果集中获取特定数量(> 1)的行(如果数据符合2 24 - 1个字节的限制)。 COM_STMT_FETCH command的字段num rows
在OP的情况下可以设置为100。
但是mysqlnd实现目前是sets this field explicitly and exclusivly to 1
所以,是的,目前你唯一的选择似乎是一个无缓冲的查询,并且一个接一个地获取记录的(小)网络开销,例如。
<?php
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'localonly', 'localonly', array(
PDO::ATTR_EMULATE_PREPARES=>false,
PDO::MYSQL_ATTR_DIRECT_QUERY=>false,
PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION
));
setup($pdo);
// use an unbuffered query
// so the complete result set isn't transfered into the php instance's memory
// before ->execute() returns
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
$stmt = $pdo->prepare('SELECT id FROM soFoo WHERE id>?');
$stmt->execute( array(5) );
$rowsPerChunk = 10;
do {
// not saying that you have to use LimitIterator, it's just one example of how you can process the chunks
// and a demonstration that PDOStatement implements Traversable
// all in all the example doesn't do very useful things ;-)
$lit = new LimitIterator(new IteratorIterator($stmt), 0, $rowsPerChunk);
doSomething($lit);
}
while( $lit->getPosition()===$rowsPerChunk);
function doSomething(Iterator $it) {
foreach($it as $row) {
printf('%2d ', $row['id']); // yeah, yeah, not that useful....
}
echo "\r\n-------\r\n";
}
function setup($pdo) {
$pdo->exec('
CREATE TEMPORARY TABLE soFoo (
id int auto_increment,
primary key(id)
)
');
$stmt = $pdo->prepare('INSERT INTO soFoo VALUES ()');
for($i=0; $i<44; $i++) {
$stmt->execute();
}
}