2013-07-09 1 views
5

Я только что тестировал исполнение Eloquent ORM в Laravel и был шокирован, чтобы найти простой запрос, занимающий более 3 секунд, чтобы выполнить по сравнению с обычным запросом Laravel, который закончился за 0,1 секунды. Я только возвращаю 1500 записей.Eloquent ORM Performance

DB::table('t_organisations')->get(); - 0.12253594398499 seconds 
Organisation::all(); - 3.6389181613922 seconds 

Несомненно, это не может быть нормальным !? Я не думаю, что что-то пропустил в настройке. Мой db нормализуется. В чем может быть проблема?

+0

Лично я бы запустил его через XDebug, чтобы узнать, где находится время. –

+1

Есть ли у вас какие-либо отношения, определенные в вашей модели? Если это так - Eloquent нужно будет делать много соединений ... – Laurence

+0

Всегда есть вещи, которые лучше всего использовать Query Builder, особенно при обработке больших данных. – crynobone

ответ

2

Спасибо за все ваши ответы.

Вот результат журнала MySQL запросов:

организации :: все(); - 1.6772060394287 сек

130710 9:52:43  5 Connect [email protected] on seltec 
      5 Prepare set names 'utf8' collate 'utf8_unicode_ci' 
      5 Execute set names 'utf8' collate 'utf8_unicode_ci' 
      5 Close stmt  
      5 Prepare select * from `users` where `id` = ? limit 1 
      5 Execute select * from `users` where `id` = '2' limit 1 
      5 Close stmt  
      5 Prepare select * from `t_organisations` 
      5 Execute select * from `t_organisations` 
130710 9:52:44  5 Close stmt  
130710 9:52:45  5 Quit 

DB :: таблица ('t_organisations') -> получить(); - 0.13963603973389 сек

130710 9:55:16  6 Connect [email protected] on seltec 
      6 Prepare set names 'utf8' collate 'utf8_unicode_ci' 
      6 Execute set names 'utf8' collate 'utf8_unicode_ci' 
      6 Close stmt  
      6 Prepare select * from `users` where `id` = ? limit 1 
      6 Execute select * from `users` where `id` = '2' limit 1 
      6 Close stmt  
      6 Prepare select * from `t_organisations` 
      6 Execute select * from `t_organisations` 
      6 Close stmt  
      6 Quit 

Так что нет разницы нет, то .... что означает задержку должны лежать в красноречивых коде PHP. Да, у меня установлен xdebug, и я не готов тратить свое время, пытаясь понять, почему это медленно! Если это быстрее в построителе запросов, для меня это достаточно хорошо!

Разработчики @Laravels: отличная работа на каркасе. Он интуитивно понятен, имеет дело с полномочиями, особенно с доверенными и доверяющими плагинами от Leroy Merlin. Вы, возможно, захотите взглянуть на проблему с выдающимся успехом!

Cheers! Craig

+0

Что значит Leroy Merlin? Entrust and Confide были написаны Zizaco [link] (https://github.com/Zizaco/confide) –

+0

Красноречивый сидит поверх Query Builder, анализируя данные, которые он возвращает в экземпляры классов.Это всегда будет медленнее, чем использование только Query Builder. Вы можете кэшировать результаты Eloquent с помощью: «Организация :: all() -> запомнить (5);». – assertchris

2

Обязательно выполните СБРОС QUERY CACHE, чтобы очистить кэш запросов MySQL между тестами. Из отмеченных вами временных меток это похоже на то, что вы сначала запросили Eloquent, а это значит, что они, вероятно, были кэшированы к тому времени, когда вы сделали второй тест. Это объясняет огромный дифференциал производительности, хотя я подозреваю, что Eloquent немного медленнее, чем обычные запросы Laravel из-за дополнительных накладных расходов.

2

Когда вы DB::table('t_organisations')->get(); Он извлекает все результаты в виде массива (или объекты), но не увлажнять их к модели. См. this stackoverflow answer, если вы хотите быстрое объяснение.

Когда вы Organisation::all(); Процесс гидратации происходит, поэтому запрос занимает больше времени (вы должны выделить все объекты в памяти и заполнить их с полями). Существует много ссылок/ссылок на оптимизацию гидратации, чтобы помочь вам лучше запросить вашу базу данных и избежать гидратации объектов, когда вам это не нужно.