#php #laravel #eloquent
Вопрос:
Я довольно новичок в laravel и sql, я заметил, что многого можно достичь с помощью различных методов. Я хочу знать, что более эффективно?
Message::where('user_id', auth()->user()->id)->get()
или
auth()->user()->messages
Кто-то, кого я знаю, предупредил меня о нетерпеливой загрузке, что это сильно влияет на производительность.
Комментарии:
1. Это не совсем проблема, но упреждающее решение возможной проблемы, с которой я могу столкнуться в будущем. Я создаю приложение для обмена сообщениями, поэтому ожидал, что моя таблица сообщений будет содержать миллионы данных. Я осознаю эффективность всех своих запросов
2. Есть и другие способы написания этих запросов, если вы действительно этого хотите. Беспокойтесь о проблемах с производительностью, если/когда вы с ними столкнетесь. До тех пор используйте любые техники, которые имеют смысл, которые приведут к достижению вашей цели (решению проблем). Я не уверен, почему кто-то сказал бы
'warn'
вам о нетерпеливой загрузке, поскольку это решает проблемуn 1
запроса при доступе к отношениям, и это хорошо, если только вы не стремитесь загружать и никогда не получаете доступ к отношениям.3. Я почти уверен, что оба показанных примера приведут к одному и тому же
messages
запросу.
Ответ №1:
Два предоставленных метода должны выполнять аналогичные запросы к базе данных в фоновом режиме. Один для извлечения пользователя, а другой для извлечения всех сообщений для этого одного пользователя. Особой разницы нет.
Это может стать проблемой, когда вы начнете извлекать вещи внутри цикла. Например:
$users = User::all();
foreach ($users as $user) {
// Messages are fetched separately for every single user inside this loop
// since the relationship is not present.
// Query like: SELECT * FROM messages WHERE user_id = ?
Log::info($user->messsages);
}
Мы можем решить эту проблему, быстро загрузив все сообщения, выполнив:
User::with('messages')->all();
Таким образом, будет выполнен только один запрос SELECT * FROM messages WHERE user_id IN (?, ?, ?, ?)
, и эти сообщения будут сопоставлены с правильными пользователями на стороне PHP. Поэтому, когда вы запускаете цикл foreach, связь уже загружена и никакие дополнительные запросы не выполняются.
В Интернете вы можете найти более подробную информацию об этом, выполнив поиск «Проблема Laravel n 1». Название происходит по той причине, что без активной загрузки в этом сценарии вы выполняете дополнительный ( 1) запрос для каждой отдельной модели. При активной загрузке это можно решить всего за 2 запроса.