我有以下查询:
select min(a) from tbl where b > ?;
,使用index(b, a)
(1500万行)在我的mysql实例上花费大约4秒钟。有没有办法加快速度?
说明:
explain select min(parsed_id) from replays where game_date > '2016-10-01';
id: 1
select_type: SIMPLE
table: replays
partitions: NULL
type: range
possible_keys: replays_game_date_index,replays_game_date_parsed_id_index
key: replays_game_date_parsed_id_index
key_len: 6
ref: NULL
rows: 6854021
filtered: 100.00
Extra: Using where; Using index
索引语句:
create index replays_game_date_parsed_id_index on replays (game_date, parsed_id);
答案 0 :(得分:1)
我认为MySQL使用的索引是正确的。该查询应该是瞬时的,因为从索引中读取一个应该返回您想要的结果。我猜对于这个查询,MySQL的SQL优化器做得很糟糕。
也许您可以改写查询以欺骗SQL优化器使用其他策略。也许您可以尝试:
select parsed_id
from replays
where game_date > '2016-10-01'
order by parsed_id
limit 1
答案 1 :(得分:0)
此版本的速度更快吗?
select @mina
fro (select (@mina := least(@mina, a)) as mina
from tbl cross join
(select @mina := 999999) params
where b > ?
) t
limit 1;
我怀疑这不会有太大的区别,但是我不确定在索引上运行如此大的聚合函数会在后台发生什么事情。
答案 2 :(得分:0)
这可能有帮助,也可能没有帮助:更改查询并添加索引:
SELECT a FROM tbl WHERE b > ? ORDER BY a LIMIT 1;
INDEX(a, b)
然后,如果匹配的b
出现在表中的时间足够早,那么它将比其他建议快。
另一方面,如果唯一匹配的b
位于表的末尾,则它将不得不扫描几乎所有索引,并且比其他选项要慢。
a
必须位于索引的第一位。通过将两个列都包含在索引中,它成为“覆盖”索引,因此速度更快。
可能可能是因为使用我的SELECT
以及两个索引将使优化器有足够的能力来选择更好的方法:
INDEX(a,b)
INDEX(b,a)
架构
添加一个(或两个)复合索引应该会有所帮助。
缩小表的大小可能会有所帮助...
INT
占用4个字节。考虑使用较小的数据类型是否足以满足这些列中的任何列。DATETIME
,TIMESTAMP
);您需要所有这些吗?fingerprint varchar(36)
是UUID / GUID吗?如果是这样,可以将其打包到BINARY(16)
中。640MB很小-检查图表以确保没有“交换”。 (交换对性能确实很不利。)