mysql - 如何加快我的 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;
解决方案
模式中有很多东西会阻碍查询速度。让我们看看什么可以做,什么不能做……
由于WHERE
和GROUP BY
命中不同的表,因此没有索引对两者都有用。最好有t0
:INDEX(event_id)
。
JOIN 的索引:t2..t6 需要在order_id
, login_id
, . 上的索引(或 PK) event_day_id
。 t1
需要INDEX(event_id, seller_order_token)
按任何顺序。
GROUP BY
and是“相同的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 the
SELECT`:
( 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 JOIN
并LIMIT
在上述讨论中添加皱纹。既然你也没有,我不会和他们讨论这个问题。
推荐阅读
- c++ - 带 ostream 和 istream 参数的构造函数
- apache-spark - 如何将 pyspark 数据帧作为参数传递给自定义地图函数(多个地图参数)
- python - python中的列表为空
- mysql - 无法将表情符号添加为注释“OperationalError :Incorrect string value: '\\xF0\\x9F\\xA5\\xB0' for column 'content' at row 1”
- c++ - C++编译器访问静态成员和访问普通成员的方式有什么区别?
- xtermjs - 如何为 xtermjs 中的滚动条设置主题?
- python - cifar10 数据集的 Resnet50(无网络权重) - 提高准确性
- xml - 如何合并两个或多个连续的 'styled-content' 元素并转换为单个 while 属性相同?
- swift - 以高于 16kHz 的采样率从 AirPod Pro 录制音频
- numpy - 与matlab逆相比,矩阵逆在python numpy中给出奇异矩阵误差