Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sqlite 虚拟表中记录的顺序不正确_Sqlite_Virtual - Fatal编程技术网

Sqlite 虚拟表中记录的顺序不正确

Sqlite 虚拟表中记录的顺序不正确,sqlite,virtual,Sqlite,Virtual,在测试SQLite虚拟表机制的实现过程中,我们遇到了一个意外的行为。 对于以下虚拟表结构: 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; explain query plan select * from VTab t1 left outer join VTab

在测试
SQLite虚拟表
机制的实现过程中,我们遇到了一个意外的行为。 对于以下
虚拟表
结构:

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;
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)
select * from VTab t1 left outer join VTab t2 on t1.ID = t2.ID order by t2.RL desc
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)
select * from Table1 t1 left outer join Table1 t2 on t1.ID = t2.ID order by t2.RL desc
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
执行计划1

select * from VTab t1 left outer join VTab t2 on t1.ID = t2.ID order by t1.RL desc;
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)
select * from VTab t1 left outer join VTab t2 on t1.ID = t2.ID order by t2.RL desc
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)
select * from Table1 t1 left outer join Table1 t2 on t1.ID = t2.ID order by t2.RL desc
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
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 t1.RL desc;
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)
select * from VTab t1 left outer join VTab t2 on t1.ID = t2.ID order by t2.RL desc
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)
select * from Table1 t1 left outer join Table1 t2 on t1.ID = t2.ID order by t2.RL desc
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
执行计划2

select * from VTab t1 left outer join VTab t2 on t1.ID = t2.ID order by t1.RL desc;
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)
select * from VTab t1 left outer join VTab t2 on t1.ID = t2.ID order by t2.RL desc
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)
select * from Table1 t1 left outer join Table1 t2 on t1.ID = t2.ID order by t2.RL desc
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
正如您所看到的,没有提到要排序的索引。 针对实际表(与我们的虚拟表具有完全相同的结构)执行的查询如下所示:

查询3

select * from VTab t1 left outer join VTab t2 on t1.ID = t2.ID order by t1.RL desc;
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)
select * from VTab t1 left outer join VTab t2 on t1.ID = t2.ID order by t2.RL desc
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)
select * from Table1 t1 left outer join Table1 t2 on t1.ID = t2.ID order by t2.RL desc
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
执行计划3

select * from VTab t1 left outer join VTab t2 on t1.ID = t2.ID order by t1.RL desc;
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)
select * from VTab t1 left outer join VTab t2 on t1.ID = t2.ID order by t2.RL desc
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)
select * from Table1 t1 left outer join Table1 t2 on t1.ID = t2.ID order by t2.RL desc
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\u index\u orderby
结构(sqlite3\u index\u info
结构的一部分)中的内容,这些结构在
xBestIndex
中没有包含任何排序信息。 另外,
orderbyconsumered
out参数返回False(因为我们的输出没有排序,我们假设它本身会对行排序)


这是SQLite虚拟表支持中的一个错误还是我们遗漏了什么?

正如
allocateIndexInfo()
中的注释所述,只有在“ORDERBY子句仅包含当前虚拟表中的列”的情况下,虚拟表才有机会实现排序。在您的查询中,排序列所来自的虚拟表仅用于查找ID列,这种单个值的查找不可用于排序



使用SQLite 3.7.14,我在查询2的计划中得到了“使用TEMP B-TREE FOR ORDER BY”。xBestIndex返回的值是什么?

问题的原因在于对
orderbyconsumered
输出标志值的处理不当

对于这个带有
JOIN
的查询,我们的
xBestIndex
实现返回了
orderbyconsumered=True
的索引,该索引在条件下匹配
,实际上是不正确的,因为在这种情况下没有进行排序。这忽略了
子句成员的任何进一步的
命令


在修复后,
orderbyconsumered
开始返回
True
仅适用于
nOrderBy
标志大于0的索引,否则返回
False

感谢您的回答。我在我的
xBestIndex
实现中发现了一个bug。它意外地为其中一个索引返回了
orderbyconsumered=True
,而根本不需要排序(对于符合条件的索引),SQLite引擎只是暗示我对我这边的所有东西都进行了排序。修复后,问题消失了。