PHP PDO缓冲查询问题

发布于 2024-07-14 05:29:49 字数 881 浏览 1 评论 0原文

我在使用 PHP 数据对象函数时遇到一些严重问题。 我试图使用缓冲查询循环遍历一个相当大的结果集(~60k 行,~1gig)以避免获取整个结果集。

无论我做什么,脚本都会挂在 PDO::query() 上 - 查询似乎正在无缓冲地运行(否则为什么结果集大小的更改会“修复”问题?)。 这是我重现问题的代码:

<?php
$Database = new PDO(
    'mysql:host=localhost;port=3306;dbname=mydatabase',
    'root',
    '',
    array(
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true
    )
);

$rQuery = $Database->query('SELECT id FROM mytable');

// This is never reached because the result set is too large
echo 'Made it through.';

foreach($rQuery as $aRow) {
    print_r($aRow);
}
?>

如果我用一些合理的数字限制查询,它工作正常:

$rQuery = $Database->query('SELECT id FROM mytable LIMIT 10');

我尝试使用 PDO::MYSQL_ATTR_MAX_BUFFER_SIZE 并使用 PDO::prepare() 和 PDO::execute() (尽管上面的查询中没有参数),两者都无济于事。 任何帮助,将不胜感激。

I'm having some serious problems with the PHP Data Object functions. I'm trying to loop through a sizeable result set (~60k rows, ~1gig) using a buffered query to avoid fetching the whole set.

No matter what I do, the script just hangs on the PDO::query() - it seems the query is running unbuffered (why else would the change in result set size 'fix' the issue?). Here is my code to reproduce the problem:

<?php
$Database = new PDO(
    'mysql:host=localhost;port=3306;dbname=mydatabase',
    'root',
    '',
    array(
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true
    )
);

$rQuery = $Database->query('SELECT id FROM mytable');

// This is never reached because the result set is too large
echo 'Made it through.';

foreach($rQuery as $aRow) {
    print_r($aRow);
}
?>

If I limit the query with some reasonable number, it works fine:

$rQuery = $Database->query('SELECT id FROM mytable LIMIT 10');

I have tried playing with PDO::MYSQL_ATTR_MAX_BUFFER_SIZE and using the PDO::prepare() and PDO::execute() as well (though there are no parameters in the above query), both to no avail. Any help would be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

只等公子 2024-07-21 05:29:49

如果我理解正确的话,缓冲查询涉及告诉 PHP 您要在开始处理之前等待整个结果集。 在 PDO 之前,这是默认设置,您必须调用 mysql_unbuffered_query 如果你想立即处理结果。

我不知道为什么 PDO MySQL 驱动程序页面上没有对此进行解释。

If I understand this right, buffered queries involve telling PHP that you want to wait for the entire result set before you begin processing. Prior to PDO, this was the default and you had to call mysql_unbuffered_query if you wanted to deal with results immediately.

Why this isn't explained on the PDO MySQL driver page, I don't know.

凑诗 2024-07-21 05:29:49

您可以尝试将其分成不会大到引起问题的块:

<?php    
$id = 0;
$rQuery = $Database->query('SELECT id FROM mytable ORDER BY id ASC LIMIT 100');

do {
    stuff($rQuery);
    $id += 100;
} while ( $rQuery = $Database->query(
            'SELECT id FROM mytable ORDER BY id ASC LIMIT 100 OFFSET '.$id
          )
        );
?>

……无论如何,您明白了。

You could try to split it up into chunks that aren't big enough to cause problems:

<?php    
$id = 0;
$rQuery = $Database->query('SELECT id FROM mytable ORDER BY id ASC LIMIT 100');

do {
    stuff($rQuery);
    $id += 100;
} while ( $rQuery = $Database->query(
            'SELECT id FROM mytable ORDER BY id ASC LIMIT 100 OFFSET '.$id
          )
        );
?>

...you get the idea, anyway.

全部不再 2024-07-21 05:29:49

或者也许你可以尝试使用 mysql 函数:

while ($row = mysql_fetch_row($query)) {
...
}

这肯定会更快,因为 foreach 语句给人的印象是使用 fetchAll() 而不是 fetch() 每行

Or maybe you could try mysql functions instead:

while ($row = mysql_fetch_row($query)) {
...
}

Which will definitely be faster, since that foreach statement makes an impression to use fetchAll() instead fetch() each row

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文