首页 > 解决方案 > 如何加快我的 MySQL 查询(JOINs + GROUP BY)

问题描述

我在 mysql 中有这个查询,因为它需要将近 20 秒才能执行,所以我想选择 insted 的有限制的内部连接,以使执行更快。

SELECT t1.order_id, CONCAT(t3.first_name,' ',t3.last_name),
    buyer_first_name, buyer_last_name, 
    max(product_quantity) as product_quantity, order_status, 
    order_value, t5.first_name staff_firstnamelogin, 
    t5.last_name staff_lastnamelogin, t6.day_name

FROM t_seller_order t0

INNER JOIN t_orders t1
                ON t0.event_id = t1.event_id 
               AND t1.seller_order_token = t0.seller_order_token

INNER JOIN t_tickets t2
                ON t1.order_id = t2.order_id

INNER JOIN t_login t3
                ON t3.login_id = t1.login_id

INNER JOIN t_login t5
                ON t0.login_id = t5.login_id

INNER JOIN t_event_days t6
                ON t2.product_id = t6.event_day_id

WHERE t0.event_id = 35

group by t1.order_id

order by order_id desc;

标签: mysqlsqlperformance

解决方案


模式中有很多东西会阻碍查询速度。让我们看看什么可以做,什么不能做……

由于WHEREGROUP BY命中不同的表,因此没有索引对两者都有用。最好有t0INDEX(event_id)

JOIN 的索引:t2..t6 需要在order_id, login_id, . 上的索引(或 PK) event_day_idt1需要INDEX(event_id, seller_order_token)按任何顺序。

GROUP BYand是“相同的ORDER BY”,所以只需要一种,而不是两种。

一个潜在的加速是GROUP BY 做一些JOINs. 当前的结构是“inflate-deflate”,其中JOINs合谋创建一个巨大的临时表,然后对GROUP BY结果进行压缩。所以...

如果看看你是否可以SELECT这样写:

SELECT t0.id, t1.id  -- I need the PRIMARY KEYs for these two tables
    FROM t_seller_order AS t0
    JOIN t_orders       AS t1
    WHERE t0.event_id = 35
    GROUP BY t1.order_id

那有多快?希望我们可以围绕这个构建查询的其余部分,但不会花费太多时间。有两种方法;我不知道哪个会更好。

计划 A: 使用子查询(如果可能)而不是JOINs. 例如,代替JOINing to t3, plan on this being one item in theSELECT`:

    ( SELECT CONCAT(first_name,' ',last_name)
          FROM t_login WHERE login_id = t1.login_id
    ) AS login_name

(对于仅接触表格一次的任何其他列也是SELECT如此。就目前而言,t5 被接触两次,因此这种方法可能不切实际。)

B计划JOIN . GROUP BY也就是说,之后“放气”。

SELECT ...
    FROM ( SELECT t0.id, t1.id ... GROUP BY... ) AS x -- as discussed above
    JOIN y  ON y.foo = x.foo
    JOIN z  ON z.bar = x.bar
    -- the GROUP BY is avoided
    ORDER BY x.order_id desc;   -- The ORDER BY is still necessary

是你的例子,我倾向于 B 计划,但两种“计划”的混合可能是可取的。

进一步说明: LEFT JOINLIMIT在上述讨论中添加皱纹。既然你也没有,我不会和他们讨论这个问题。


推荐阅读