【问题标题】:PDO Sqlite `fetchAll()` exhausting all memoryPDO Sqlite `fetchAll()` 耗尽所有内存
【发布时间】:2016-02-08 07:14:19
【问题描述】:

我有以下使用 PDO 连接到我的 Sqlite3 数据库并计算所有记录的 PHP 脚本:

<?php

ini_set('max_execution_time', 300);
error_reporting(E_ALL);
ini_set("display_errors", 1);

$db = new PDO('sqlite:db/MYDB.sl3');
$result = $db->query('SELECT * FROM MYTABLE');
$rows = $result->fetchAll();
$row_count = count($rows);

echo "Rows: " . $row_count . "\n";

?>

如果我从 shell (PHP-CLI) 运行它,一切都会好的:

Rows: 175412

但从网络运行它会引发以下错误:

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 14 bytes) in /var/www/test/sqlitepdo.php on line 9

在 PHP 中设置内存不是一个解决方案,因为这甚至不应该发生,因为 MySQL 不会发生与示例相同的结果。

有什么想法吗?

【问题讨论】:

    标签: php pdo sqlite


    【解决方案1】:

    因此,您正在创建一个包含 175K 行的数组,只是为了计算行数。这势必会产生内存问题。即使您设法解决了这个问题,这样做也毫无意义。

    为了深入了解,134217728 字节 ~ 134 MB。因此,每次调用该查询时,您将读取超过 134 MB 的数据,即使您设法抑制错误,这本身就是一个问题。

    您可以简单地更改您的查询以询问 sqllite row count 是什么。

    SELECT count(*) as c FROM MYTABLE
    

    那么你只有 1 行的行数,使用它。

    $row = $result->fetch(PDO::FETCH_ASSOC);
    echo "Rows: " . $row["c"] . "\n";
    

    This 可以帮助解答为什么在 CLI 模式下不产生错误

    【讨论】:

    • SQLite 对COUNT(*) 进行了特殊优化,但对COUNT(anything else) 没有。
    • 是的,这行得通。请在答案中编辑双 echo,以便我接受。
    猜你喜欢
    • 2015-08-23
    • 1970-01-01
    • 2014-10-04
    • 2014-01-16
    • 2012-11-10
    • 2012-08-19
    • 2011-02-09
    • 2015-10-01
    • 2018-12-11
    相关资源
    最近更新 更多