2016-02-08 2 views
0

У меня есть следующий скрипт, который использовать PDO для подключения к базе данных sqlite3 и сосчитать все записи:PDO Sqlite `fetchAll()` исчерпывает всю память

<?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"; 

?> 

все хорошо, если я запускаю его из оболочки (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 такими же результатами, как пример.

Любая идея?

ответ

2

Итак, вы создаете массив с 175K строк, просто для подсчета количества строк. Это неизбежно создает проблемы с памятью. Даже если вам удастся решить, что это бессмысленно делать.

Для проницательности, 134217728 байт ~ 134 МБ. Таким образом, вы читаете более 134 МБ данных для каждого запроса этого запроса, что само по себе является проблемой, даже если вам удастся устранить ошибку.

Вы можете просто изменить свой запрос, чтобы спросить sqllite, что такое row count.

SELECT count(*) as c FROM MYTABLE 

Тогда у вас есть только 1 строка со счетом, используйте это.

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

This может помочь ответить почему он не генерирует ошибку в режиме CLI

+0

SQLite имеет специальную оптимизацию для 'COUNT (*)', но не для 'COUNT (все остальное)'. –

+0

Да, это работает. Пожалуйста, просто отредактируйте двойное 'echo' в ответе, чтобы я мог его принять. – bsteo

+0

Обе вещи обновлены –

Смежные вопросы