此查询的执行时间超过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
答案 0 :(得分:0)
将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
原始查询是体验性能约束的原因是由于ON子句中使用的公式,RDBMS被迫对b
中的每一行执行a
的全表扫描。
即使“更快”的查询需要b
的全表扫描才能生成“临时”表tmp_b
,但它能够使用a.timestamp_a
上的索引来提取相应的来自a
的值基于以下条件: tmp_b.timestamp_b_minus AND tmp_b.timestamp_b_plus