我正在尝试加快此查询:
SELECT order.id
FROM (
SELECT o.id
FROM `order` as `o`
INNER JOIN order_item as oi on
oi.order_id = o.id
AND `o`.`canceled` = 0
AND ( `o`.`return_date` > "2011-03-14" OR oi.checked = 0 OR '2011-03-14' < oi.last_update)
) as `order`
时钟为 0.0930 秒。子查询 (SELECT * FROM order
as o
...) 在 0.0005 秒处有自己的时钟。我正在测试的表有大约 10000 行,从子查询 where 子句返回 43 行。
除了加快查询速度之外,如果有人能向我解释为什么当我将查询包装在另一个查询中时查询速度会慢 100 多倍,我真的很高兴?
MySql explain 告诉我它自己的子查询首先选择 o
,然后是 oi
。 MySql 对整个查询的解释首先选择(什么是 derived2?),然后依次选择 o
和 oi
。
我希望子查询成为一个子查询,因为我正在做很多不在 where 子句中的连接(我已从代码和基准测试中排除)。如果我单独使用子查询和连接,查询会更慢。
任何帮助将不胜感激。我已经搜索了答案但找不到,这可能只是因为我不知道要寻找什么,如果是这样,我深表歉意。
最佳答案
MySQL
在对内联 View 执行任何操作之前对其进行缓冲。
0.0006
秒,您看到的第一个查询很可能是响应时间(提取的第一行),而不是总时间(提取的最后一行)。
如果 id
是 order
表上的 PRIMARY KEY
,则不需要 GROUP BY
在上面。
如果每个订单有很多商品(平均每个订单超过 20
个商品),您可以尝试创建以下索引:
order_item (order_id, checked)
order_item (order_id, last_update)
并将相关子查询一分为二:
SELECT *
FROM order o
WHERE o.canceled = 0
AND
(
o.return_date > '2011-03-14'
OR
(
SELECT MIN(checked)
FROM order_item oi
WHERE order_id = o.id
) = 0
OR
(
SELECT MAX(last_update)
FROM order_item oi
WHERE oi.order_id = o.id
) > '2011-03-14'
)
同样,这仅在您的每件商品有很多订单时才有用,否则对所有订单进行一次扫描会更有效率。
关于MySql select from subquery 慢(即使子查询本身很快),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5453993/