如果可能的话,我想提高以下查询的效率:
SELECT * FROM orders o
INNER JOIN order_items oi
ON o.id = oi.order_id
WHERE o.fulfilled = false
AND o.id NOT IN (SELECT order_id
FROM order_items
WHERE sku = '011111'
GROUP BY order_id
HAVING COUNT(order_id) = 1)
订单和order_items表之间存在一对多的关系(o.id = oi.order_id)。
目标是从两个表中选择所有信息,条件如下:
订单尚未履行(orders.fulfilled = false)。
排除所有订单项目的所有订单,其中SKU为' 011111' (oi.sku喜欢' 011111')。
感谢任何帮助!
答案 0 :(得分:0)
IN可以更慢,修改查询以使用内连接
select * from orders o
inner join order_items oi
on o.id = oi.order_id
and o.fulfilled = false
inner join( select order_id
from order_items
where sku != '011111'
group by order_id
having count(order_id) = 1) T
on T.order_id = oi.id
答案 1 :(得分:0)
count(whatever)
通常会强制进行全表扫描(因为它不知道有多少订单按order_items分组,你不能在聚合上创建索引),除非有另一个子句可以使用指数。很可能sku不等于某些东西不够有选择性(我猜你有很多skus。)你可以查看explain
输出,你可能会看到{{1}的全表扫描你查询的一部分。
如果是这种情况,那么您可以选择缓存计数数据,然后通过trigger函数对其进行索引,该函数在每次下订单或完成订单时更新IN
列。或者,您可以缓存一个跟踪计数的查询(例如,如果信息不需要刷新很多。)
答案 2 :(得分:0)
我们可以假设订单在同一订单上不能有多个具有相同sku的商品吗? 我们可以假设你没有订单没有商品吗?
如果是这样,写相反的可能会更快。以下查询查找除' 011111'以外的任何sku的所有订单。此外,相关子查询通常比非相关子查询更快(尽管优化器足够聪明,可以在很多时候重写它)。 Exists子句通常比in子句更快,因为引擎可以在查看所有子查询行之前退出。
SELECT *
FROM orders o
INNER JOIN order_items oi
ON o.id = oi.order_id
WHERE o.fulfilled = false
AND EXISTS (SELECT 'x'
FROM order_items oi2
WHERE o.order_id = oi2.order_id
AND sku != '011111')