3

メカニズムの実装のテスト中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)

D1xBestIndexこれは、メソッドの実装によって生成された値であり、フィールド#1=RLによる降順の並べ替えを意味します。 ここで、フィールド#0=IDの同等の操作をC0=0意味します。これは期待どおりに機能します。

ただし、次のクエリは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、並べ替えに関する情報は含まれていませんでした。また、orderByConsumedoutパラメーターはFalseを返します(出力は順序付けられておらず、自体が行を順序付けすると想定しているため)。

これはサポートのバグSQLite Virtual Tableですか、それとも何かを逃しましたか?

4

2 に答える 2

2

のコメントにあるallocateIndexInfo()ように、仮想テーブルは、「ORDERBY句に現在の仮想テーブルの列のみが含まれている」場合にのみ順序付けを実装する機会があります。クエリでは、並べ替え列の元となる仮想テーブルはID列を検索するためにのみ使用され、このような単一値の検索は順序付けには使用できません。


SQLite 3.7.14では、クエリ2のプランで「USETEMP B-TREE FOR ORDERBY」が表示されます。xBestIndexによって返される値は何ですか?

于 2012-09-16T10:52:00.890 に答える
2

orderByConsumed問題の理由は、出力フラグ値 の不適切な処理にありました。

を使用したこのクエリのJOIN場合、xBestIndex実装は条件にorderByConsumed = True一致するインデックスを返しましたONが、その場合は順序付けが行われなかったため、実際には正しくありませんでした。これにより、それ以降のORDER BY句メンバーは無視されました。

修正が開始された後、フラグが0より大きいインデックスおよびそれ以外のインデックスのみorderByConsumedが返されます。TruenOrderByFalse

于 2012-09-19T16:16:01.117 に答える