orderby / where查询SQL中的哪种索引?
我想在一个SQLite数据库上运行一个查询
SELECT a,b,c,d FROM data WHERE a IN (1,2,3) ORDER BY b,c
我应该使用什么类型/顺序的索引来启用SQLite(或者以后的MySQL)来快速执行此操作? 如何轻松检查查询是否被索引增强(即如何解释EXPLAIN)? 如果我将d
包含在索引中,SQLite会更快吗?
编辑:这是表格的特征:
a
b
c
PS:当SQLite / MySQL可以使用索引时,有没有可以学习的参考?
如果且仅当IN (1,2,3)
是常量列表(总是相同的值),则可以使用如下的部分索引:
CREATE INDEX so ON data (b,c) WHERE a IN (1,2,3)
然后运行你的查询给出这个计划( explain query plan select...
):
0|0|0|SCAN TABLE data USING INDEX so
0|0|0|EXECUTE LIST SUBQUERY 1
注意:没有ORDER BY
操作。
作为反击测试,让我们放下索引并将其替换为:
CREATE INDEX so ON data (a,b,c);
新的执行计划是:
0|0|0|SEARCH TABLE data USING INDEX so (a=?)
0|0|0|EXECUTE LIST SUBQUERY 1
0|0|0|USE TEMP B-TREE FOR ORDER BY
你现在看到排序操作了吗?
我还没有生成任何有意义的测试数据(只是一张空表)来验证执行速度的提高。 但我想你应该在创建索引后马上看到它。
另请注意,自SQLite 3.8.0(2013-08-26发布)以来,仅支持部分索引。
需要考虑的一个小问题是:如果在a in (1, 2, 3)
上过滤,会发现多少行? 如果这是表格的很大一部分,可能已经高达15%左右,使用索引甚至可能会降低性能。
将此与图书索引进行比较。 假设索引是完整的,这意味着所有单词都被索引。 如果您正在查找“和”的出现次数,并且您使用此索引,则您将无法从索引跳转到文本并返回。 简单地从封面阅读本书到封面,扫描“和”肯定是更快的选择。
目前尚不清楚盈亏平衡点在哪里,因为它取决于很多因素。 但它低于大多数人的想象。 (我已经提到了15%,根据我的经验,这是一个很好的规则)
如果排序可以省略,使用索引仍然是一个选项。 在这种情况下(b, c, a)
树索引将具有列(b, c, a)
。 (散列索引对此没有帮助)。 根据数据类型和更新频率,您甚至可以考虑使用(b, c, a, d)
作为索引。 DBMS只需要执行索引扫描,而不是表扫描。 (如果d
很大,它不会有太大的帮助,并且会损坏很多空间;如果d
经常更新,也可能是一个坏主意,因为它会使更新的工作量加倍)。
物理数据库设计通常是找到正确的折中方案。
好的,编辑后我的很多文字都不再适用了。 不过,我认为答案可能会让你思考一些事情。
以下索引可帮助您快速获取记录 - 当然,dbms认为使用索引的速度要快于全表扫描。 例如,如果它认为in(1,2,3)将获得表中90%的记录,则应避免使用索引,而只是简单地扫描整个表。
CREATE INDEX idx ON data(a);
以下索引可帮助您快速获取记录,甚至快速排序。 同样,如果dbms认为使用索引是错误的,则不会使用此索引。 但是使用这个索引的可能性更大,因为dbms不仅获得哪些记录可以访问的信息,而且还会让它们排序。
CREATE INDEX idx ON data(a,b,c);
以下索引可帮助您快速获取记录并快速排序,甚至无需访问表格。 这里所有的数据都存在于索引中,所以dbms没有理由不使用索引。 它就在那里:获得想要的数据的标准,它的排序,甚至数据本身已经存在。
CREATE INDEX idx ON data(a,b,c,d);
链接地址: http://www.djcxy.com/p/62067.html
上一篇: What kind of index for orderby/where query in SQL?
下一篇: Delete rows where certain value occurs more than once SQL