如何加快我的MySQL查询(JOINs + GROUP BY)

时间:2018-08-27 18:32:34

标签: mysql sql performance

我在mysql中有此查询,由于要花近20秒钟才能执行,因此我想对有限制的innerjoins进行选择,以使执行速度更快。

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;

1 个答案:

答案 0 :(得分:0)

关于架构的许多事情阻碍了查询的速度。让我们看看可以做什么或不能做什么...

由于 public static IEnumerable<TReturn> Query<TReturn>(this IDbConnection cnn, string sql, Type[] types, Func<object[], TReturn> map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) WHERE命中了不同的表,因此没有索引对两者有用。最好是拥有GROUP BY t0

JOIN的索引:t2..t6需要INDEX(event_id)order_idlogin_id上的索引(或PK)。 event_day_id需要以任何顺序使用t1

INDEX(event_id, seller_order_token)GROUP BY是“相同”的,因此只需要一种,而不是两种。

可能的加速效果是在完成某些ORDER BY之前先完成GROUP BY 。当前的结构是“ inflate-deflate”,其中JOINs共同创建了一个巨大的临时表,然后JOINs缩小了结果。所以...

如果可以这样写GROUP BY

SELECT

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

计划A:(请尽可能使用子查询)代替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 。例如,代替JOINs SELECT`:

JOINing to t3, plan on this being one item in the

( SELECT CONCAT(first_name,' ',last_name) FROM t_login WHERE login_id = t1.login_id ) AS login_name 中其他仅接触表一次的列的Ditto。就目前而言,t5接触了两次,所以这种方法可能不切实际。)

计划B: SELECT之后的JOIN 。也就是说,然后“放气”。

GROUP BY

以您的例子为例,我倾向于B计划,但是可能需要同时使用这两个“计划”。

更多说明: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 LEFT JOIN在上面的讨论中增加了皱纹。由于您都没有,所以我不会与他们进行混乱的讨论。