Я использую Laravel 4.2, и мое приложение используется для отслеживания инвентаря в нескольких местах.Laravel orWhere()/MySQL или запрос занимает много времени
База данных создана с 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
) время запроса до 1s непосредственно с Sequel Pro, более 5с через мое приложение Laravel (или через ремесленник повозиться). Без этих «или» проверок (т. Е. Просто проверяя один тип количества, например «зарезервировано»), запрос равен < 100 мс на Sequel Pro и аналогичен в приложении/tinker.
Я не уверен, почему добавление этих дополнительных «или» проверок добавляет столько времени на запрос. Любые идеи, как сделать более результативный запрос?
У вас есть указатели на поля 'зарезервированные',' доступные', 'входящие',' total' таблицы? – num8er
В общем случае «или» условия делают возможными выполнение запроса. Кроме того, механизм базы данных никогда не делает статический путь, когда вы используете эти типы динамических условий. Так что может потребоваться больше времени, чем на подготовленный путь –
@ num8er да, у меня есть индексы на каждом и попробовали несколько индексов (не уверен в правильной терминологии для этого) –