Я использую Laravel 4.2, и мое приложение используется для отслеживания запасов в нескольких местах.
База данных настроена с таблицей inventory_items
, таблицей inventory_locations
и сводной таблицей между ними inventory_items_inventory_location
, которая содержит значения количества, ссылаясь как на элемент инвентаря, так и на местоположение, которому принадлежит запись.
Мой запрос состоит в том, чтобы найти элементы инвентаря, у которых любое значение количества местоположения больше или равно 0. В Laravel я использую подзапрос и orWhere следующим образом:
InventoryItem::whereHas('inventoryLocations', function($q) {
$q->where('reserved', '>=', 0)
->orWhere('available', '>=', 0) # slow
->orWhere('inbound', '>=', 0) # slow
->orWhere('total', '>=', 0); # slow
})->toSql();
Что дает следующий SQL:
select * from `inventory_items`
where `inventory_items`.`deleted_at` is null
and (
select count(*) from `inventory_locations`
inner join `inventory_item_inventory_location`
on `inventory_locations`.`id` = `inventory_item_inventory_location`.`inventory_location_id`
where `inventory_item_inventory_location`.`inventory_item_id` = `inventory_items`.`id`
and `reserved` >= ?
or `available` >= ? # slow
or `inbound` >= ? # slow
or `total` >= ? # slow
) >= 1
Проблема в том, что с операторами or
(отмеченными в коде #slow
) время запроса составляет до 1 с непосредственно с Sequel Pro, более 5 с через мое приложение Laravel (или через ремесленника). Без этих проверок «или» (т. е. просто проверки одного типа количества, например, «зарезервировано») запрос составляет ‹100 мс в Sequel Pro и аналогичен в приложении/мастере.
Я не уверен, почему добавление этих дополнительных проверок «или» добавляет так много времени к запросу. Любые идеи, как сделать более производительный запрос?
reserved
,available
,inbound
,total
? - person num8er   schedule 30.12.2016available
,inbound
иtotal
? - person Rwd   schedule 30.12.2016>=
на>
, потому что я не вижу логикиwhereHas('inventoryLocations')
. Я имею в виду, что вам нужно проверить существованиеinventoryLocations
, если данные больше нуля. потому что>=
может вернуть все данные. - person num8er   schedule 30.12.2016=, >, <
и т. д. - person Mr Office   schedule 30.12.2016