多列索引是否适用于单列选择?

时间:2009-04-28 05:40:05

标签: sqlite indexing

我(例如)有一个索引:

CREATE INDEX someIndex ON orders (customer, date);

此索引是否只会加速使用 customer和date 的查询,还是会加速像这样的单列查询?

SELECT * FROM orders WHERE customer > 33;

我正在使用SQLite。


如果答案是肯定的,为什么每个表可以创建多个索引?


还有一个问题:当您在查询中使用两列时,组合索引与两个分离索引相比要快多少?

3 个答案:

答案 0 :(得分:38)

marc_s对你的第一个问题有正确答案。多键索引中的第一个键可以像单个键索引一样工作,但任何后续键都不会。

至于复合索引的速度有多快取决于您的数据以及如何构建索引和查询,但这通常很重要。索引基本上允许Sqlite对字段进行二进制搜索。

使用您在运行查询时提供的示例:

SELECT * from orders where customer > 33 && date > 99

Sqlite首先会在整个表格上使用二进制搜索获得所有结果,其中客户> 33.然后它只对那些寻找日期>的结果进行二元搜索。 99。

如果您在客户和日期对两个单独的索引执行相同的查询,则Sqlite必须对整个表进行二次搜索,首先针对客户,然后再针对日期。

因此,您将看到多少速度增加取决于您根据查询构建索引的方式。理想情况下,索引中的第一个字段和查询应该是消除最可能匹配的字段,因为这会通过大大减少第二次搜索必须完成的工作量来提高速度。

有关详细信息,请参阅: http://www.sqlite.org/optoverview.html

答案 1 :(得分:5)

我很确定这会起作用,是的 - 无论如何它都适用于MS SQL Server。

但是,如果您只需要选择日期,则此索引不会对您有所帮助,例如日期范围。在这种情况下,您可能需要仅在日期上创建第二个索引,以使这些查询更有效。

马克

答案 2 :(得分:3)

我通常使用组合索引来分类我希望分页或请求“流畅”的数据。

假设客户可以生成多个订单..并且存在客户0到11,并且每个客户都有多个订单,所有订单都是以随机顺序插入的。我想根据客户编号和日期对查询进行排序。您应该对id字段进行排序,最后将客户具有多个相同日期的集合分开(即使可能永远不会发生)。

sqlite> CREATE INDEX customer_asc_date_asc_index_asc ON orders
          (customer ASC, date ASC, id ASC);

获取已排序查询的第1页(限制为10个项目):

sqlite> SELECT id, customer, date FROM orders
          ORDER BY customer ASC, date ASC, id ASC LIMIT 10;

2653|1|1303828585
2520|1|1303828713
2583|1|1303829785
1828|1|1303830446
1756|1|1303830540
1761|1|1303831506
2442|1|1303831705
2523|1|1303833761
2160|1|1303835195
2645|1|1303837524

获取下一页:

sqlite> SELECT id, customer, date FROM orders WHERE
          (customer = 1 AND date = 1303837524 and id > 2645) OR
          (customer = 1 AND date > 1303837524) OR
          (customer > 1)
          ORDER BY customer ASC, date ASC, id ASC LIMIT 10;

2515|1|1303837914
2370|1|1303839573
1898|1|1303840317
1546|1|1303842312
1889|1|1303843243
2439|1|1303843699
2167|1|1303849376
1544|1|1303850494
2247|1|1303850869
2108|1|1303853285

等等......

当您使用查询OFFSET和LIMIT时,使用索引会减少服务器端索引扫描。查询时间越长,驱动器越大,偏移越高。使用这种方法可以消除这种情况。

如果您计划稍后加入数据,但建议每个请求只需要一组有限的数据,建议使用此方法。如上所述加入SUBSELECT以减少大型表的内存开销。

相关问题