我们有以下MySQL表,大约有1.5亿行:
CREATE TABLE `data` (
`datetime` datetime NOT NULL,
`value1` decimal(12,6) NOT NULL,
`value2` decimal(12,6) NOT NULL,
`value3` decimal(12,6) NOT NULL,
`value4` decimal(12,6) NOT NULL,
`value5` decimal(12,6) NOT NULL,
`symbol_id` int(11) NOT NULL,
PRIMARY KEY (`symbol_id`,`datetime`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1.5亿行均匀分配在9500个符号之间,由symbol_id指定。
我正在尝试在表上运行以下查询:
SELECT datetime FROM data WHERE symbol_id = 1234 AND datetime <= "2013-03-01 15:00:00" ORDER BY datetime DESC LIMIT 1
在查询上运行EXPLAIN返回:
id: 1
select_type: SIMPLE
table: data
type: range
possible_keys: PRIMARY
key: PRIMARY
key_len: 12
ref: NULL
rows: 23856
Extra: Using where; Using index
查询平均需要大约300毫秒才能运行。我可以添加什么索引来加快速度?
谢谢!
答案 0 :(得分:2)
正如戈登所暗示的那样,没有可以提高查询性能的索引。
这并不是说你没有办法让它更快 - 调整你的DBMS和OS I / O--你没有提供任何关于它当前配置的信息,也没有提供它运行的信息以及使用模式是什么喜欢。如果你还没有启动这个过程,那么对你的安装运行mysqltuner.pl将是一个好的开始 - 但它并不总是完全正确。使用不同的引擎可以提高此查询的性能 - 但这取决于系统上发生的所有其他事情。
通过在多个磁盘上分割索引和/或使用SSD作为索引存储,您将获得巨大收益。更多内存几乎总是有帮助。
在MySQL调优上转到get a good book,花时间阅读它。
答案 1 :(得分:0)
使用索引可以改进此查询的性能,但首先必须确定列的基数。
SELECT COUNT(DISTINCT `datetime`) FROM `data`;
SELECT COUNT(DISTINCT `symbol_id`) FROM `data`;
无论哪个返回最大数量的唯一值具有更高的基数并且具有最佳的复合索引,列必须按基数的降序排列。
您目前拥有一个复合主键,其列按以下顺序排列。
PRIMARY KEY (`symbol_id`,`datetime`)
如果symbol_id的基数高于datetime,则无法进一步优化查询。另一方面,如果datetime具有更高的基数,那么您应该添加一个带有datetime的索引,后跟symbol_id。
INDEX idx_datetime_symbol (`datetime`,`symbol_id`)