我刚刚使用InnoDB引擎发现了MySQL的以下行为。有没有办法解释执行时间的显着差异?
第一次查询:
SELECT ask FROM history_time WHERE ask> 1.5790 AND timestamp BETWEEN 1207000800290 AND 1207690900290
执行时间:0.715秒
EXPLAIN: '1', 'SIMPLE', 'history_time', 'range', 'PRIMARY,timestamp,ask,ask_2', 'PRIMARY', '8', NULL, '3278190','Using where'
第二次查询:
SELECT ask FROM history_time WHERE ask> 1.5790 AND timestamp > 1207000800290
执行时间:0.002秒
EXPLAIN: '1', 'SIMPLE', 'history_time', 'range', 'PRIMARY,timestamp,ask,ask_2', 'ask', '4', NULL, '5850604', 'Using where; Using index'
第三次质询:
SELECT ask FROM history_time WHERE ask> 1.5790 AND timestamp < 1207690900290
执行时间:0.651秒
EXPLAIN: '1', 'SIMPLE', 'history_time', 'range', 'PRIMARY,timestamp,ask,ask_2', 'PRIMARY', '8', NULL, '3278190', 'Using where'
EXPLAIN告诉我,只有第二个查询使用索引。我的桌子包含83 Mio.行,主键是时间戳。我还有一个索引(ask,timestamp)和一个关于ask(这是多余的,仅用于测试目的)。为什么MySQL只在第二个查询中使用索引?
答案 0 :(得分:1)
你的答案在于:The Range Access Method for Multiple-Part Indexes
编辑:你还最好检查一下:mysql range index。优化器有可能决定使用全扫描然后索引会更快。
答案 1 :(得分:0)
您的查询专门按时间戳作为主键,但也可以通过您的评论(ask,timestamp)查询。交换它...你想要在第一个位置使用较小的粒度...(时间戳,询问)......除非你要求一个非常具体的询问值或询问值范围。可以这样想。
如果你有8300万行并且你要求在X和Y的时间范围内发生的事情,时间戳是你的基础......为什么要考虑任何低于或大于有问题的范围。现在,您添加“ask&gt; someValue”,优化器可能会感到困惑。猜猜..是否有更少的值大于ask值,或者更少的值基于提供的时间戳范围。如果你有一个索引(时间戳,问),它将能够更好地利用它。在提供的范围内,只提出问题&gt; someValue中。
如果优化器使用当前的Ask索引,它基本上会遍历所有大于提供值的条目......然后在每个条目中跳转到时间戳范围内的那些条目。
现在,交换您的标准。如果您正在寻找特定的“询问”值或范围,那么您当前的指数将非常好。它只关注那个范围。