在测试SQLite Virtual Table
机制的实现过程中,我们遇到了意外的行为。
对于以下virtual table
结构:
create table X(ID int, RL real)
该查询按RL的正确降序返回所有记录
领域。
查询1:
select * from VTab t1 left outer join VTab t2 on t1.ID = t2.ID order by t1.RL desc;
执行计划1:
explain query plan select * from VTab t1 left outer join VTab t2 on t1.ID = t2.ID order by t1.RL desc;
0|0|0| SCAN TABLE VTab AS t1 VIRTUAL TABLE INDEX 0:D1; (~0 rows)
0|1|1| SCAN TABLE VTab AS t2 VIRTUAL TABLE INDEX 4:C0=0; (~0 rows)
D1
这是由我们的xBestIndex
方法实现生成的值,表示按字段#1 = RL降序排序。C0=0
此处表示字段#0 = ID的相等操作。这按预期工作。
但是,下一个查询返回的行(
RL
字段的别名不同)没有任何排序。查询2:
select * from VTab t1 left outer join VTab t2 on t1.ID = t2.ID order by t2.RL desc
执行计划2:
explain query plan select * from VTab t1 left outer join VTab t2 on t1.ID = t2.ID order by t2.RL desc;
0|0|0| SCAN TABLE VTab AS t1 VIRTUAL TABLE INDEX 0: (~0 rows)
0|11| SCAN TABLE VTab AS t2 VIRTUAL TABLE INDEX 4:C0=0; (~0 rows)
如您所见,没有提到要排序的索引。
针对真实表(具有与我们的虚拟表相同的结构)执行的查询如下所示:
查询3:
select * from Table1 t1 left outer join Table1 t2 on t1.ID = t2.ID order by t2.RL desc
执行计划3:
explain query plan select * from Table1 t1 left outer join Table1t2 on t1.ID = t2.ID order by t2.RL desc;
0|0|0| SCAN TABLE Table1 AS t1 (~1000000 rows)
0|1|0| SEARCH TABLE Table1 AS t2 USING AUTOMATIC COVERING INDEX (ID=?)
0|1|0| (~7 rows)
0|0|0| USE TEMP B-TREE FOR ORDER BY
如您所见,这里使用
B-tree
进行排序。从我们这边,我们检查了
sqlite3_index_orderby
结构(sqlite3_index_info
结构的一部分)在到达xBestIndex
时所收到的内容,它们不包含任何有关排序的信息。同样,
orderByConsumed
out参数返回False(因为我们的输出未排序,并且我们假定sqlite本身将对行进行排序)。这是
SQLite Virtual Table
支持中的错误还是我们错过了什么? 最佳答案
正如allocateIndexInfo()
中的注释所述,只有在“ ORDER BY子句仅包含当前虚拟表中的列”的情况下,您的虚拟表才有机会实施排序。在查询中,sort列来自的虚拟表仅用于查找ID列,并且此类单个值的查找不可用于排序。
使用SQLite 3.7.14,我在查询2的计划中确实得到了“ USE TEMP B-TREE FOR ORDER BY”。xBestIndex返回的值是什么?