Я создал приложение с Laravel, в котором у меня довольно глубокие отношения, которые мне иногда нужно запрашивать.База данных - MySQL.
Например, я хочу получить всех пользователей , которым разрешено читать книгу .Мои данные структурированы следующим образом:
- A Пользователь принадлежит 0-n UserGroups через UserMembership
- A UserGroup имеет 0-n Права
- A Право относится к 1 Книге и описывает, какие действия могут бытьВыполнено
После просмотра и просмотра я обнаружил, что некоторые люди рекомендуют следующий способ для решения вложенных отношений:
// class Book extends Model
public function readers() {
$bookId= $this->id;
return User::whereHas('memberships', function($m) use($bookId) {
$m->whereHas('group', function($g) use($bookId) {
$g->whereHas('rights', function($r) use($bookId) {
$r->where('resource_id', $bookId)->where('action', 'read');
});
});
});
}
Мне нравится, что код имеет большой смысл,но производительность ужасна .. Время выполнения составляет 430 мс в среднем для Book::find(967)->readers()->get()
Я переписал функцию следующим образом:
public function readersNew() {
$bookId= $this->id;
$g = Right::where('resource_id', $bookId)->where('action', 'read')->pluck('group_id');
$uIds = UserMembership::whereIn('group_id', $g)->pluck('user_id');
return User::whereIn('id', $uIds);
}
С этим кодомЯ достигаю среднего времени исполнения 4 мс , что, очевидно, намного лучше.Но это также выглядит гораздо менее «методично» с точки зрения написания вложенных запросов.
Мне бы очень хотелось понять:
- почему reader () -> get () намного медленнее, чем readerNew () -> get ()
- что лучше всего написать такие запросы