Laravel orWhere()/ MySQL或查询需要很长时间
我使用的是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,超过通过我的Laravel应用程序(或通过工匠鼓捣)5秒。如果没有这些'或'检查(即只检查一种数量类型,例如'保留'),则在Sequel Pro上的查询是< 100ms,而在应用/修补程序上则是类似的。
我不确定为什么添加这些额外的'或'检查会为查询增加太多时间。任何想法如何使一个更高性能的查询?
查看结果查询及其WHERE条件。你肯定会错过一些括号那里,我想你需要的是
where `inventory_item_inventory_location`.`inventory_item_id` = `inventory_items`.`id`
and (
`reserved` >= ?
or `available` >= ? #
or `inbound` >= ?
or `total` >= ?
)
,而不是
where `inventory_item_inventory_location`.`inventory_item_id` = `inventory_items`.`id`
and `reserved` >= ?
or `available` >= ? # slow
or `inbound` >= ? # slow
or `total` >= ?
它导致全表扫描这是带有大量行的表非常缓慢。
为了解决这个问题,更换
InventoryItem::whereHas('inventoryLocations', function($q) {
$q->where('reserved', '>=', 0)
->orWhere('available', '>=', 0) # slow
->orWhere('inbound', '>=', 0) # slow
->orWhere('total', '>=', 0); # slow
})->toSql();
与
InventoryItem::whereHas('inventoryLocations', function($q) {
$q->where(function($subquery) {
$subquery->where('reserved', '>=', 0)
->orWhere('available', '>=', 0)
->orWhere('inbound', '>=', 0)
->orWhere('total', '>=', 0);
});
})->toSql();
退房MySQL的EXPLAIN命令,可以让你分析如何查询将被执行,多少行会被质疑 - http://dev.mysql.com/doc/refman/5.7/en/explain.html
完美 - 现在可以对它进行子查询了解更多关于它是如何工作的。将在未来调查解释这类问题。谢谢 –
您是否在表格的'reserved','available','inbound','total'字段中添加了索引? – num8er
在一般的“或”条件下可以执行查询。此外,当您使用这些类型的动态条件时,数据库引擎也不会创建静态路径。所以它可能需要更多的时间比准备好的路径 –
@ num8er是的,我有每个索引,并尝试过多个指数(不知道这是适当的术语) –