我在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;
答案 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_id
,login_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
在上面的讨论中增加了皱纹。由于您都没有,所以我不会与他们进行混乱的讨论。