SQLite:使用范围查询上的索引进行查询优化
这是我真正问题的简化版本:有一个表,有两列,表上有一个索引。就是SQLite:使用范围查询上的索引进行查询优化,sql,sqlite,Sql,Sqlite,这是我真正问题的简化版本:有一个表,有两列,表上有一个索引。就是 CREATE TABLE T (a integer primary key, b integer not null); CREATE INDEX Ti on T (b, a); 列a是主键,因此是唯一的,但列b可以有许多重复项。这个问题是这样的 SELECT * from T where b=5 and a>3 order by b, a limit 1; 我的期望是,只要一次二进制搜索就足以找到满足条件的最小(b,a)
CREATE TABLE T (a integer primary key, b integer not null);
CREATE INDEX Ti on T (b, a);
列a是主键,因此是唯一的,但列b可以有许多重复项。这个问题是这样的
SELECT * from T where b=5 and a>3 order by b, a limit 1;
我的期望是,只要一次二进制搜索就足以找到满足条件的最小(b,a)对,如果它充分利用索引的话。此外,特别声明:
如果索引的初始列(列a、b等)出现在WHERE子句中,则可以使用索引。索引的初始列必须与=或IN或IS NULL运算符一起使用使用的最右边的列可以使用不等式。对于使用的索引的最右边的列,最多可以有两个不等式,必须将该列的允许值夹在两个极端之间
但是explain
和explain查询计划的结果非常令人失望。(sqlite3.8.8.3)
显然,它只使用索引来定位b=5的第一行,然后进行线性扫描以查找a>3的行。当只有少数行具有重复的b值时,这可能是正常的,但在其他情况下可能会出现问题。与p4=1的SeekGE相比,p4=2的SeekGT和p4=1的IdxGT效率更高,因为它只需一次二进制搜索就可以直接定位正确的行
所以问题是,如果你说这就是目前的情况,我当然无能为力,但以防万一,我遗漏了什么可以让它更好地工作的东西吗ANALYZE
不是一个选项,因为这意味着有一种通常更好的方法来处理范围查询,而不仅仅是针对特定的数据集
sqlite> explain query plan select * from T where b=5 and a>3 order by b,a limit 1;
0 0 0 SEARCH TABLE T USING COVERING INDEX Ti (b=?)
sqlite> explain select * from T where b=5 and a>3 order by b,a limit 1;
5 SeekGE 2 14 2 1 00
6 IdxGT 2 14 2 1 00
7 IdxRowid 2 3 0 00
8 Le 4 13 3 54
9 Copy 3 5 0 00
10 Column 2 0 6 00
11 ResultRow 5 2 0 00
12 IfZero 1 14 -1 00
13 Next 2 6 0 00