簡體   English   中英

在MySQL中使用BETWEEN的執行時間很長

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM