我有一个看起来像这样的表:
CREATE TABLE foo (type integer, priority integer);
'type'是少数值之一。
我想进行查询以选择按优先级排序的某种类型的样本行:
SELECT * FROM foo WHERE type = 0 ORDER BY priority DESC LIMIT 100;
我正在尝试创建一个索引以使其快速。但似乎sqlite不允许我处理以下两种情况:
我可以让sqlite使用其中任何一个,但我无法弄清楚是否有可能有一个单一的索引/查询对两种情况都有效。似乎(类型,优先级)上的索引可以工作,但看起来sqlite只用于第一次查找而不是ORDER BY。
答案 0 :(得分:1)
两列上的单个索引允许使用在两种情况下都有效的执行计划:
> CREATE INDEX t_p ON foo(type, priority);
> EXPLAIN QUERY PLAN SELECT * FROM foo WHERE type = 0 ORDER BY priority DESC LIMIT 100;
0|0|0|SEARCH TABLE foo USING COVERING INDEX t_p (type=?)
> .explain on
> EXPLAIN SELECT * FROM foo WHERE type = 0 ORDER BY priority DESC LIMIT 100;
addr opcode p1 p2 p3 p4 p5 comment
---- ------------- ---- ---- ---- ------------- -- -------------
0 Trace 0 0 0 00
1 Noop 0 0 0 00
2 Integer 100 1 0 00
3 Goto 0 15 0 00
4 OpenRead 2 3 0 k(3,B,B,B) 00
5 Integer 0 2 0 00
6 SeekLe 2 13 2 1 00
7 IdxLT 2 13 2 1 00
8 Column 2 0 4 00
9 Column 2 1 5 00
10 ResultRow 4 2 0 00
11 IfZero 1 13 -1 00
12 Prev 2 7 0 00
13 Close 2 0 0 00
14 Halt 0 0 0 00
15 Transaction 0 0 0 00
16 VerifyCookie 0 2 0 00
17 TableLock 0 2 0 foo 00
18 Goto 0 4 0 00
首先,SQLite打开索引并快速搜索type
列小于或等于零(6 SeekLe
)的最后一条记录。
然后它返回索引的结果,向后(12 Prev
),直到遇到type
列小于零(7 IdxLT
)的索引条目。
这是对索引的单次扫描,永远不需要跳过不需要的条目。