MySql 从子查询中选择速度很慢(尽管子查询本身很快)

发布于 2024-10-27 07:50:17 字数 819 浏览 6 评论 0原文

我正在尝试加快此查询的速度:

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 行,其中 43 行是从子查询 where 子句返回的。

除了加快查询速度之外,我真的很希望有人能向我解释为什么当我将查询包装在另一个查询中时查询会变慢 100 倍以上?

MySql 解释告诉我,子查询本身首先选择 o,然后选择 oi。 MySql 对整个查询的解释首先选择(什么是导出2?),然后按顺序选择ooi

我希望子查询成为子查询,因为我正在执行大量不在 where 子句中的联接(我已将其从代码和基准中排除)。如果我单独使用子查询和连接,查询会更慢。

任何帮助将不胜感激。我已经寻找答案但找不到答案,这可能只是因为我不知道要寻找什么,如果是这样,我很抱歉。

I'm trying to speed up this query:

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`

It clocks at 0.0930 seconds. The subquery (SELECT * FROM order as o...) on it's own clocks at 0.0005 seconds. The table I'm testing on has about 10000 rows, 43 rows are returned from subqueries where-clause.

Except from speeding up the query, I'd really like it if someone could explain to me why the query becomes more than 100 times slower when I wrap it within another query?

MySql explain tells me that the subquery on it's own first selects o, and then oi. MySql explain for the whole query first selects (what is derived2?), then o and oi in that order.

I'd like the subquery to be a subquery because I'm doing a lot of joins which aren't in the where clause (which I've excluded from the code and the benchmarks). If I'd use the subquery on it's own, with the joins, the query would be even slower.

Any help would be much appreciated. I've searched for answers but can't find them, and that might just be because I do not know what to look for, if so, I apologize.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

萤火眠眠 2024-11-03 07:50:18

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

您在第一个查询中看到的 0.0006 秒很可能是响应时间(提取的第一行),而不是总时间(提取的最后一行)。

如果 idorder 表上的 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 buffers the inline view before doing any operations on it.

0.0006 seconds you see for the first query is most probably the response time (the first row fetched), not the overall time (the last row fetched).

If id is a PRIMARY KEY on your order table, you don't need a GROUP BY on it.

If you have lots of items per order (more than about 20 items per order in average or so), you can try creating the following indexes:

order_item (order_id, checked)
order_item (order_id, last_update)

and splitting your correlated subquery in two:

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'
        )

Again, this will only help if you have lots of orders per items, otherwise a single scan on all orders will be more efficient.

风苍溪 2024-11-03 07:50:18
  1. 检查索引
  2. 您是否优化了正在使用的表?
  3. 如果将 SELECT 语句中的“*”更改为所需列的实际名称,查询将运行得更快。
  4. 您是否需要多个 GROUP BY“订单 id” - 一个在另一个中?
  1. check indexes
  2. did you optimize tables that you are working with ?
  3. query will work faster if you'll change "*" in the SELECT statement to actual names of columns that you need.
  4. do you need multiple GROUP BY "order id" - one inside another?
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文