[英]Long execution time with BETWEEN in MySQL
此查詢的執行時間超過2秒(對於10k行)。 是否可以優化此查詢?
SELECT id, MIN(ABS(timestamp_a - timestamp_b))
FROM a
INNER JOIN b ON ( timestamp_a between (timestamp_b - 5 * 60)
AND (timestmap_b + 5 * 60) )
GROUP BY id
示例結果(id,timestamp_a,timestamp_b,diff):
1 1349878538 1349878539 1
2 1349878679 1349878539 2
3 1349878724 1349878539 1
5 1349878836 1349878539 1
6 1349878890 1349878641 1
表a
CREATE TABLE `a` (
`id` int(11) NOT NULL AUTO_INCREMENT ,
`timestamp_a` bigint(20) NULL DEFAULT NULL ,
PRIMARY KEY (`id`),
INDEX `a` (`timestamp_a`) USING BTREE
)
表b
CREATE TABLE `b` (
`id` int(11) NOT NULL AUTO_INCREMENT ,
`timestamp_b` bigint(20) NULL DEFAULT NULL ,
PRIMARY KEY (`id`),
INDEX `b` (`timestamp_b`) USING BTREE
)
兩個表之間沒有相關性 - 我搜索表'a'中的記錄,這些記錄位於表'b'中的時間戳之間。
編輯:簡單的解決方案(運行速度非常快):
SELECT id, MIN(ABS(timestamp_a - timestamp_b))
FROM (SELECT id, timestamp, (timestamp - 5 * 60) timestamp_a, (timestamp + 5 * 60) timestamp_b) a
INNER JOIN b ON ( timestamp between timestamp_a AND timestamp_b )
GROUP BY id
將Michael的約定用於修改后的時間戳列,此查詢將生成原始查詢的預期結果,並具有上述“更快”查詢的性能:
SELECT a.id, MIN(ABS(a.timestamp_a - tmp_b.timestamp_b))
FROM (SELECT id, timestamp_b, (timestamp_b - 5 * 60) timestamp_b_minus, (timestamp_b + 5 * 60) timestamp_b_plus) tmp_b
INNER JOIN a ON ( a.timestamp_a between tmp_b.timestamp_b_minus AND tmp_b.timestamp_b_plus )
GROUP BY a.id
究其原因,原來的查詢體驗性能限制是,RDBMS被強制執行全表掃描b
在每行a
,由於ON子句中使用的公式。
即使“更快”的查詢需要b
的全表掃描來生成“臨時”表tmp_b
它也能夠使用a.timestamp_a
上的索引從a
提取適當的值,基於以下標准: tmp_b.timestamp_b_minus AND tmp_b .timestamp_b_plus
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.