私はLaravel 4.2を使用しています。私のアプリケーションは、複数の場所にまたがる在庫を追跡するために使用されています。Laravel orWhere()/ MySQLまたはクエリが長時間かかる
データベースは、inventory_items
テーブルで設定それらinventory_items_inventory_location
間inventory_locations
テーブルとピボットテーブル、レコードが属する在庫アイテムと場所の両方を参照しながら量の値を含むされます。次のSQLを与える
InventoryItem::whereHas('inventoryLocations', function($q) {
$q->where('reserved', '>=', 0)
->orWhere('available', '>=', 0) # slow
->orWhere('inbound', '>=', 0) # slow
->orWhere('total', '>=', 0); # slow
})->toSql();
:
私のクエリは、私はサブクエリとorWhereので、などを使用していLaravelは0より以上の等しい任意の場所の数量値を持つインベントリ項目を見つけることです。
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
問題は(#slow
によってコードでマーク)or
文でクエリ時間が私のLaravelアプリから(または職人いじくり経由)続編Proは、より多くの5Sと直接1Sまでであるということです。これらの 'または'小切手がない場合(つまり、1つの数量タイプ、たとえば '予約済み'のチェックのみ)、クエリはSequel Proの< 100msであり、アプリ/ティッカーでも同様です。
これらの余分な 'または'チェックを追加すると、なぜクエリに時間がかかるのかわかりません。どのようによりパフォーマンスの高いクエリを作成するためのアイデア?
haveテーブルの 'reserved'、' available'、 'inbound'、' total'フィールドにインデックスを追加しましたか? – num8er
一般的に「または」条件では、クエリ実行の可能性があります。また、これらのタイプの動的条件を使用すると、データベースエンジンは決して静的パスを作成しません。だから、準備されたパスよりも多くの時間がかかるかもしれない –
@ num8erはい、私はそれぞれのインデックスを持っていますし、複数のインデックスを試しても(そのための適切な用語がわからない) –