MySQL BETWEEN查询 - 哪个部分使用索引?

时间:2014-10-16 21:45:10

标签: mysql sql database indexing database-optimization

假设我在foo(bar:int)上有一个正常的btree索引的表bar,该表包含100行(bar的值为2到101)。运行以下查询时,MySQL如何决定是先执行>=还是<=

SELECT bar from foo where bar BETWEEN 0 AND 1

如果它执行了>=那么它将扫描所有100行。另一方面,如果它执行了<=,它将进行0次扫描。有没有办法指定先做哪个?

对于包含多年历史数据的非常大的表的datetime范围查询以及请求的时间范围接近当前时间,这对我来说尤其重要。如果它首先执行<=那么就会对多年的数据进行大量扫描。例如:

SELECT * from table 
WHERE instant BETWEEN DATE_SUB(NOW(), INTERVAL 1 HOUR) AND DATE_SUB(NOW(), INTERVAL 1 MINUTE);

1 个答案:

答案 0 :(得分:1)

如果我正确理解你的问题:当创建B树索引时,它通常是B +树 http://en.wikipedia.org/wiki/B%2B_tree

B+ Tree representation

维基百科:&#34;一个简单的B +树示例,将密钥1-7链接到数据值d1-d7。链表(红色)允许快速按顺序遍历。&#34;

这意味着在大约log_b(N)时间内找到范围中的最小元素(在您的情况下是最早的日期)然后 从B +树的所有叶子中都有k个跳跃,直到该范围内的所有元素都耗尽为止。

k是数据库中存在的元素数量而不是所有可能的值,N是树的高度(在维基百科示例中它是2),b是树的分支因子(在维基百科的例子是3)

修改 例:

  • 在只有foo&lt; = 1的情况下,它进入B +树并且找不到任何东西,所以我们有0次扫描。

  • 在只有foo&gt; = 0的情况下,它不会找到0,而是第一个在它的值中,在你的情况下它会变为2。然后它将进行100次扫描

  • 如果您在40&#39;之间有&#39; foo 0它就像foo&lt; = 40 AND foo&gt; = 0,所以它会转到第一个,在你的情况下转到2然后再做(假设所有值都在数据库中的38hopes /扫描)。换句话说,它们不是单独执行的,因此它们将一起使用索引!

一般情况下,Sql server具有优化器,可以检测范围并通过将AND按正确的顺序重写查询。他们还会跟踪查询性能,并在估算出要遵循的执行计划的成本计划后做出决定。如果您有SQL Server,则可以使用任何查询查看所有这些计划。