MySql从子查询中选择慢(即使它自己的子查询很快)

时间:2011-03-28 02:13:00

标签: mysql select subquery

我正在尝试加快此查询:

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 ordero ...)在它自己的时钟上为0.0005秒。我正在测试的表有大约10000行,从子查询where子句返回43行。

除了加快查询速度之外,如果有人能向我解释为什么当我将查询包装在另一个查询中时,查询速度会慢100多倍,我真的很喜欢它?

MySql解释告诉我,它自己的子查询首先选择o,然后选择oi。 MySql解释整个查询首先选择(什么是derived2?),然后按顺序选择ooi

我希望子查询成为子查询,因为我正在做很多不在where子句中的连接(我已从代码和基准中排除)。如果我自己使用子查询,使用连接,查询会更慢。

非常感谢任何帮助。我已经找到了答案,却找不到答案,这可能只是因为我不知道该找什么,如果有的话,我道歉。

2 个答案:

答案 0 :(得分:1)

MySQL在对其进行任何操作之前缓冲内联视图。

您在第一个查询中看到的

0.0006秒很可能是响应时间(第一行被提取),而不是总时间(最后一行被提取)。

如果id表格中PRIMARY KEYorder,则表示您不需要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'
        )

同样,这只会在每件商品有大量订单时有所帮助,否则对所有订单进行单次扫描会更有效。

答案 1 :(得分:0)

  1. 检查索引
  2. 您是否优化了与之合作的表格?
  3. 如果您将SELECT语句中的“*”更改为您需要的列的实际名称,
  4. 查询将更快地运行。
  5. 你需要多个GROUP BY“订单ID” - 一个在另一个内吗?