findAll и PHP - помогите найти проблему.

Общие вопросы по использованию фреймворка. Если не знаете как что-то сделать и это про Yii, вам сюда.
anton-ny
Сообщения: 18
Зарегистрирован: 2011.12.22, 12:28

findAll и PHP - помогите найти проблему.

Сообщение anton-ny »

В MySQL таблица products, в ней 2 000 000 записей. Занимает в MyIsam 263.9 МБ. Индексы настроены.
Если выполнить

Код: Выделить всё

$criteria=new CDbCriteria;
$criteria->limit = 10000;
return count(Products::model()->findAll($criteria));
 
то кол-во возвращается, а если выполнить

Код: Выделить всё

$criteria=new CDbCriteria;
$criteria->limit = 20000; // и более (либо без лимита)
return count(Products::model()->findAll($criteria));
 
то белый пустой экран, никакой ошибки. Логи ошибок apache молчат.
Подскажите, куда копать?
esche
Сообщения: 1054
Зарегистрирован: 2010.11.24, 03:39

Re: findAll и PHP - помогите найти проблему.

Сообщение esche »

памяти не хватает?
p.s. для получения количества лучше всё же пользовать Products::model()->count()
...
anton-ny
Сообщения: 18
Зарегистрирован: 2011.12.22, 12:28

Re: findAll и PHP - помогите найти проблему.

Сообщение anton-ny »

Допустим дело в памяти, проверим:
Выполняю в PHPMyAdmin команду

Код: Выделить всё

SELECT COUNT( * ) 
FROM  `products` 
LIMIT 50000
Ответ

Код: Выделить всё

COUNT(*)
2229145
Ещё для примера:

Код: Выделить всё

SELECT * 
FROM  `shop_products` 
LIMIT 50000
Ответ:

Код: Выделить всё

Отображает строки 0 - 29 (50,000 всего, запрос занял 0.0388 сек.)
Хотя странно что написано 0-29, но отображает все.. очень долго, но грузит страницу!
kmtz
Сообщения: 26
Зарегистрирован: 2011.04.23, 11:18

Re: findAll и PHP - помогите найти проблему.

Сообщение kmtz »

У вас очень странная проверка. В посте вы делаете выборку, у вас в памяти находится огромный массив из 20к элементов и вы считаете количество элементов в массиве, а в "проверке" - делаете нормальный count средствами БД.
anton-ny
Сообщения: 18
Зарегистрирован: 2011.12.22, 12:28

Re: findAll и PHP - помогите найти проблему.

Сообщение anton-ny »

Согласен, проверка с count не корректная получилась.

Ну а как же запрос

Код: Выделить всё

SELECT * 
FROM  `shop_products` 
LIMIT 50000
Его результат разве не попадает в память?
Jampire
Сообщения: 207
Зарегистрирован: 2011.01.28, 11:45
Откуда: Гомель
Контактная информация:

Re: findAll и PHP - помогите найти проблему.

Сообщение Jampire »

anton-ny писал(а):Допустим дело в памяти, проверим:
Выполняю в PHPMyAdmin команду
А причем здесь count и пхп в вашем примере?
Запрос, который вы посылаете в phpmyadmin:

Код: Выделить всё

SELECT COUNT( * ) FROM  `products`;
Запрос, который вы посылаете через yii:

Код: Выделить всё

SELECT  * FROM  `products`;
И потом на результирующий массив применяете функцию count(). Разницу чувствуете?
Если хотите проверить память, напишите на голом пхп:

Код: Выделить всё

<?php

$dbh = new PDO($dsn, $user, $password);
$sht = $dbh->prepare('SELECT * FROM products');
$sth->execute();
$result = $sth->fetchAll();
echo count($result);
Изображение
Человек, говорящий, что это невозможно сделать, не должен мешать тому, кто это делает.
anton-ny
Сообщения: 18
Зарегистрирован: 2011.12.22, 12:28

Re: findAll и PHP - помогите найти проблему.

Сообщение anton-ny »

Код: Выделить всё

$dbh = new PDO($dsn, $user, $password);
$sth = $dbh->prepare('SELECT * FROM products LIMIT 100000');
$sth->execute();
$result = $sth->fetchAll();
echo count($result);
Уже лучше, до 100 000 строк он считает, а больше - белый экран.
kmtz
Сообщения: 26
Зарегистрирован: 2011.04.23, 11:18

Re: findAll и PHP - помогите найти проблему.

Сообщение kmtz »

Вам действительно нужен массив со всеми этими данными? Вы планируете выводить на экран единоразово таблицу из 100 000 строк? Чем вас не устраивает select count(id)?
anton-ny
Сообщения: 18
Зарегистрирован: 2011.12.22, 12:28

Re: findAll и PHP - помогите найти проблему.

Сообщение anton-ny »

kmtz писал(а):Вам действительно нужен массив со всеми этими данными? Вы планируете выводить на экран единоразово таблицу из 100 000 строк? Чем вас не устраивает select count(id)?
Да, мне нужен массив с примерно 20 000 - 50 000 строк.
Это дело должно выгрузиться в Excel5-файл через PHPExcel библиотеку.

Куда дальше копать?
kmtz
Сообщения: 26
Зарегистрирован: 2011.04.23, 11:18

Re: findAll и PHP - помогите найти проблему.

Сообщение kmtz »

Хорошо, задача хоть ясна теперь ). И если задача именно такая - то копать в сторону увеличения выделения памяти, либо пользоваться другими средствами.
anton-ny
Сообщения: 18
Зарегистрирован: 2011.12.22, 12:28

Re: findAll и PHP - помогите найти проблему.

Сообщение anton-ny »

kmtz писал(а):Хорошо, задача хоть ясна теперь ). И если задача именно такая - то копать в сторону увеличения выделения памяти, либо пользоваться другими средствами.
1. Полное отсутствие ошибок на экране и в логах это нормально в данном случае?
2. Можете привести пример, какими средствами ещё можно воспользоваться для решения задачи?
esche
Сообщения: 1054
Зарегистрирован: 2010.11.24, 03:39

Re: findAll и PHP - помогите найти проблему.

Сообщение esche »

anton-ny писал(а):2. Можете привести пример, какими средствами ещё можно воспользоваться для решения задачи?
Не храните единовременно все записи в памяти (fetch без All) - разбирайте по одному ряду, (или формируйте буфер из нескольких рядов) и его выкатывайте в выходной файл. Как вариант - можно отказаться от использования AR в пользу DAO - 100к рядов уже разберётся
по поводу ошибок - смотрите настройки сервера/php - обычно вылезает что-то вроде "Allowed memory size of .. bytes exhausted"
...
anton-ny
Сообщения: 18
Зарегистрирован: 2011.12.22, 12:28

Re: findAll и PHP - помогите найти проблему.

Сообщение anton-ny »

esche писал(а):Не храните единовременно все записи в памяти (fetch без All) - разбирайте по одному ряду, (или формируйте буфер из нескольких рядов) и его выкатывайте в выходной файл. Как вариант - можно отказаться от использования AR в пользу DAO - 100к рядов уже разберётся
по поводу ошибок - смотрите настройки сервера/php - обычно вылезает что-то вроде "Allowed memory size of .. bytes exhausted"
Вы предлагаете делать не один запрос к базе на 100к строк, а 100к запросов к базе по одной строке? Мне кажется это будет ооочень долго.
По поводу DAO я ещё подумаю, это хоть временный но выход. А мой предел в 100к строй увеличить как-то можно? Пробовал увеличивать memory_limit для PHP - всё тоже самое.
esche
Сообщения: 1054
Зарегистрирован: 2010.11.24, 03:39

Re: findAll и PHP - помогите найти проблему.

Сообщение esche »

anton-ny писал(а):Вы предлагаете делать не один запрос к базе на 100к строк, а 100к запросов к базе по одной строке? Мне кажется это будет ооочень долго.
По поводу DAO я ещё подумаю, это хоть временный но выход. А мой предел в 100к строй увеличить как-то можно? Пробовал увеличивать memory_limit для PHP - всё тоже самое.
Я точно такое предлагаю? :)
memory_limit - не всегда можно увеличить без php.ini - смотрите "реальное" значение в скрипте
...
anton-ny
Сообщения: 18
Зарегистрирован: 2011.12.22, 12:28

Re: findAll и PHP - помогите найти проблему.

Сообщение anton-ny »

esche писал(а):Я точно такое предлагаю? :)
Я что-то не так понял? Тогда разжуйте уж пожалуйста для меня.
esche писал(а):memory_limit - не всегда можно увеличить без php.ini - смотрите "реальное" значение в скрипте
Выставляю в php.ini
Как посмотреть "реальное" значение в скрипте не представляю, ведь скрипт до конца не отрабатывает - белый экран.
Подглядываю сколько ест процесс httpd (apache) в top-е. Жрёт прилично:
mysqld - 461M
apache - >300M
esche
Сообщения: 1054
Зарегистрирован: 2010.11.24, 03:39

Re: findAll и PHP - помогите найти проблему.

Сообщение esche »

anton-ny писал(а):Я что-то не так понял? Тогда разжуйте уж пожалуйста для меня.
Не храните единовременно все записи в памяти (fetch без All) - разбирайте по одному ряду,
1 запрос, много записей.. из результата получать одну запись, обрабатывать её и складывать в нужном виде куда надо (в файл?). При этом в памяти массив с данными для обработки вместо 100к*X будет занимать X байт

Код: Выделить всё

ini_get('memory_limit'); 
...
anton-ny
Сообщения: 18
Зарегистрирован: 2011.12.22, 12:28

Re: findAll и PHP - помогите найти проблему.

Сообщение anton-ny »

esche писал(а):1 запрос, много записей.. из результата получать одну запись, обрабатывать её и складывать в нужном виде куда надо (в файл?). При этом в памяти массив с данными для обработки вместо 100к*X будет занимать X байт

Код: Выделить всё

ini_get('memory_limit');  
Ну а результат-то из которого надо брать одну запись где? Опять же в памяти?

ini_get('memory_limit') даёт правильные 750M
esche
Сообщения: 1054
Зарегистрирован: 2010.11.24, 03:39

Re: findAll и PHP - помогите найти проблему.

Сообщение esche »

anton-ny писал(а):Ну а результат-то из которого надо брать одну запись где? Опять же в памяти?
Да попробуйте же fetch без All http://www.php.net/manual/en/pdostatement.fetch.php

Код: Выделить всё

   $stmt->execute();
    while ($row = $stmt->fetch(PDO::FETCH_NUM, PDO::FETCH_ORI_NEXT)) {
      $data = $row[0] . "\t" . $row[1] . "\t" . $row[2] . "\n";
      print $data;
    } 
...
d4rkr00t
Сообщения: 15
Зарегистрирован: 2010.09.03, 20:27

Re: findAll и PHP - помогите найти проблему.

Сообщение d4rkr00t »

Может скрипту тупо не хватает времени на исполнение, попробуйте увеличить set_time_limit ( int $seconds ) вроде 0 неограниченное время.
anton-ny
Сообщения: 18
Зарегистрирован: 2011.12.22, 12:28

Re: findAll и PHP - помогите найти проблему.

Сообщение anton-ny »

d4rkr00t писал(а):Может скрипту тупо не хватает времени на исполнение, попробуйте увеличить set_time_limit ( int $seconds ) вроде 0 неограниченное время.
Пробовал.
Ответить