我的查询使用索引的时间过多。 如何为Mysql查询创建良好的索引?
查询
SELECT `id`, `time`, `volume`, `candle` FROM `forex_history`
WHERE
period='30m' AND
id IN ('40','1817')
ORDER BY `time` DESC
LIMIT 600;
表中的9500万行
慢查询日志:
# Query_time: 3.801843 Lock_time: 0.000076 Rows_sent: 600 Rows_examined: 10966
# Rows_affected: 0 Bytes_sent: 49296
10%的查询速度很慢。 查询需要0.2秒到30秒
表架构:
执行计划:
答案 0 :(得分:0)
我可以建议以下索引:
CREATE INDEX idx ON forex_history (period, time, volume, candle);
-- add id if not using InnoDB
此索引将涵盖整个WHERE
子句以及SELECT
。
您可以尝试使用其他两个版本:
(period, id, time, volume, candle)
(period, id, time)
答案 1 :(得分:0)
我同意蒂姆的回答……最具体地说(时间,id,时间)的索引。
此外,由于您的“ id”列为整数,因此请消除引号,使其成为隐含字符串。让数据类型正确,以防止类型/广播混淆。
SELECT id, time, volume, candle
FROM forex_history
WHERE period='30m'
AND id IN ( 40, 1817 )
ORDER BY time DESC
LIMIT 600;
现在,正如蒂姆(Tim)也提到基数,我们对此以及您的数据集一无所知。您最好做一个UNION,然后限制。这就是为什么。您有95+百万条记录。假设ID 40有18万条记录,ID 1817有另外90k条记录。您必须先下拉27万条记录,然后才能应用订单。
如果您执行的联合中每个ID的最大限制为600,那么您将获得MOST 1200记录,然后对这1200条记录按其各自的最佳时间进行排序,即使给定ID都是单边的也是如此
SELECT
id, time, volume, candle
from
( SELECT id, time, volume, candle
FROM forex_history
WHERE period='30m'
AND id = 40
ORDER BY time DESC
LIMIT 600
UNION ALL
SELECT id, time, volume, candle
FROM forex_history
WHERE period='30m'
AND id = 1817
ORDER BY time DESC
LIMIT 600 ) PQ
order by time desc
limit 600
答案 2 :(得分:-1)
将时间转换为数字并按时创建索引。