2013-05-29 4 views
4

Я только начал играть с Laravel 4 и Eloquent. У меня есть таблица блога и много других связанных таблиц к нему:Eloquent делает много запросов

blog <- main info about the blog record 
blog_lang <- translations for each blog record 
blog_categories <- name speaks for itself 
blog_categories_lang <- translations for blog categories titles 
blog_to_categories <- pivot table between blog and blog_categories 

blog hasMany blog_lang. 
blog_categories hasMany blog_categories_lang 
blog belongsToMany blog_categories 

Я хочу, чтобы показать следующую информацию в одной сетке: blog_id, blog_title, username, и все категории:

$data['blogs'] = Blog::with(array(
    'translations' => function ($q) { 
    $q->where('lang_id', '=', 1); 
    }, 
    'user', 
    'categories', 
    'categories.translations' => function ($q) { 
    $q->where('lang_id', '=', 1); 
    } 
))->get(); 

Это выполняет 5 запросов ... не слишком ли они слишком много? Будет ли лучше использовать Fluent и соединить все эти таблицы с 1 большим запросом?

ответ

14

Eloquent сделать много маленьких, индексированные запросы гораздо лучше вещь, чем делать один большой запрос для широкого спектра причин:

  • MySQL не будет загружать несколько таблиц во временной памяти для каждого запроса и может повторно использовать их между запросами
  • SQL-оптимизатор будет работать более быстро через каждый запрос
  • Это позволяет кэшировать результаты без необходимости выбрасывать JOIN с (и другими аналогичными положениями) из данных, который упрощает кэширование

Вы на самом деле не замечая этого, но путь, пройденный SQL оптимизатора то же самое между следующими запросами:

SELECT a.*, b.* FROM a INNER JOIN b ON (a.id=b.id) WHERE a.id = 1 

SELECT a.*, b.* FROM a, b WHERE a.id = b.id AND a.id = 1 

Оба они будут вызывать SQL оптимизатор для выполнения этих запросов понятные капотом:

SELECT a.* WHERE a.id = 1 

SELECT b.* WHERE b.id = 1 

И оттуда, в зависимости от индексов, оптимизатор SQL будет выполнять сопоставления, либо на основе indioces или полных данных таблицы. Что делает Красноречивый? Именно эти два вопроса. Вы ничего не получаете по одному большому запросу - на самом деле, вы теряете возможность повторного использования данных. Во всем, предпочитайте небольшие, оптимизированные, повторно используемые, кэшируемые запросы для громоздких операторов.

+0

Чтобы расширить свой ответ ... один огромный объединенный запрос также обеспечит избыточные столбцы/строки во всех отношениях, кроме атрибутов, принадлежащих To или hasOne, поскольку вам потребуется одна запись на самую глубокую ссылку в отношениях - противно! –

+1

Спасибо большое ^^ Я не могу проголосовать за ваш ответ, потому что мне не хватает, но я проверил его как принятый. Еще раз спасибо вам обоим ^^ Cheers – faust

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