优化订单事件的相关子查询 table
Optimize correlated subquery for order events table
我有一个带有订单事件的 MariaDB table:
EVENTID
ORDERID
DATA
TIMESTAMP
1
1
'stuff1'
2021-12-17 11:48:00.000
2
1
'newstuff1'
2021-12-17 11:49:00.000
3
1
'newerstuff1'
2021-12-17 11:49:30.000
4
2
'stuff2'
2021-12-17 11:50:00.000
5
3
'stuff3'
2021-12-17 11:51:10.000
6
3
'newstuff3'
2021-12-17 11:52:00.000
而且我需要获取每个订单的最新事件。
所以对于这个数据集,结果应该是
EVENTID
ORDERID
DATA
TIMESTAMP
3
1
'newerstuff1'
2021-12-17 11:49:30.000
4
2
'stuff2'
2021-12-17 11:50:00.000
6
3
'newstuff3'
2021-12-17 11:52:00.000
我正在使用相关子查询实现此目的:
SELECT *
FROM MESSAGES m1
WHERE TIMESTAMP = (SELECT MAX(TIMESTAMP)
FROM MESSAGES m2 WHERE m1.ORDERID = m2.ORDERID);
但这对于大量数据来说速度很慢,所以我想知道是否有一种方法可以使用连接或分组来改进查询。否则,如果有帮助,我愿意将数据分成不同的 tables。
SELECT *
FROM table t1
WHERE NOT EXISTS ( SELECT NULL
FROM table t2
WHERE t1.orderid = t2.orderid
AND t1.`timestamp` < t2.`timestamp` )
即如果没有另一行具有相同的订单 ID 和最近的日期,则只需 select 行。
PS。 (orderid, `timestamp`)
的索引会有所改善。
SELECT m3.*
FROM ( SELECT ORDERID, MAX(TIMESTAMP) AS TIMESTAMP
FROM MESSAGES m1
GROUP BY ORDERID ) m2
JOIN MESSAGES m3 USING(ORDERID, TIMESTAMP);
并且有
INDEX(ORDERID, TIMESTAMP)
查询是“groupwise-max”模式。
派生的 table(子查询)将跳过索引,然后从 table.
中查找其余列
如果给定的订单 ID 有任何重复的时间戳,它将传送多行。如果不需要,请参阅 this 了解更多选项。
我有一个带有订单事件的 MariaDB table:
EVENTID | ORDERID | DATA | TIMESTAMP |
---|---|---|---|
1 | 1 | 'stuff1' | 2021-12-17 11:48:00.000 |
2 | 1 | 'newstuff1' | 2021-12-17 11:49:00.000 |
3 | 1 | 'newerstuff1' | 2021-12-17 11:49:30.000 |
4 | 2 | 'stuff2' | 2021-12-17 11:50:00.000 |
5 | 3 | 'stuff3' | 2021-12-17 11:51:10.000 |
6 | 3 | 'newstuff3' | 2021-12-17 11:52:00.000 |
而且我需要获取每个订单的最新事件。 所以对于这个数据集,结果应该是
EVENTID | ORDERID | DATA | TIMESTAMP |
---|---|---|---|
3 | 1 | 'newerstuff1' | 2021-12-17 11:49:30.000 |
4 | 2 | 'stuff2' | 2021-12-17 11:50:00.000 |
6 | 3 | 'newstuff3' | 2021-12-17 11:52:00.000 |
我正在使用相关子查询实现此目的:
SELECT *
FROM MESSAGES m1
WHERE TIMESTAMP = (SELECT MAX(TIMESTAMP)
FROM MESSAGES m2 WHERE m1.ORDERID = m2.ORDERID);
但这对于大量数据来说速度很慢,所以我想知道是否有一种方法可以使用连接或分组来改进查询。否则,如果有帮助,我愿意将数据分成不同的 tables。
SELECT *
FROM table t1
WHERE NOT EXISTS ( SELECT NULL
FROM table t2
WHERE t1.orderid = t2.orderid
AND t1.`timestamp` < t2.`timestamp` )
即如果没有另一行具有相同的订单 ID 和最近的日期,则只需 select 行。
PS。 (orderid, `timestamp`)
的索引会有所改善。
SELECT m3.*
FROM ( SELECT ORDERID, MAX(TIMESTAMP) AS TIMESTAMP
FROM MESSAGES m1
GROUP BY ORDERID ) m2
JOIN MESSAGES m3 USING(ORDERID, TIMESTAMP);
并且有
INDEX(ORDERID, TIMESTAMP)
查询是“groupwise-max”模式。
派生的 table(子查询)将跳过索引,然后从 table.
中查找其余列如果给定的订单 ID 有任何重复的时间戳,它将传送多行。如果不需要,请参阅 this 了解更多选项。