式SQLite3
を使用して(3.18)でインデックスを作成しようとしていますjson_extract
。私の目的は、結果を生成するためにインデックスのみを必要とするクエリを実行することです。これは、json_extract
大きなデータセットや値を操作するときにパフォーマンスを低下させる高価な操作であるためです。私は自分のニーズに合うカバリングインデックスが必要だと結論しました。
ステップ1-通常のテーブル構造を使用して理論をテストする
CREATE TABLE Player (
Id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
FirstName TEXT NOT NULL,
MiddleName TEXT,
LastName TEXT NOT NULL
);
CREATE INDEX Player_FirstName ON Player (
FirstName ASC,
LastName ASC
);
EXPLAIN QUERY PLAN SELECT
FirstName, LastName
FROM
Player
WHERE
LENGTH(LastName) > 10
ORDER BY
FirstName
LIMIT
10
OFFSET
0
収量
SCAN TABLE Player USING COVERING INDEX Player_FirstName
これはまさに私が期待していることです。クエリプランナーPlayer_FirstName
は、このORDER BY
句のためにインデックスが適切であると判断し、WHERE
ステートメントはそのインデックスにもある値のみを操作するため、テーブルを読み取る必要がありません。最後に、SELECT
ステートメントにはインデックス付きの列のみが含まれるため、テーブルにまったく触れないクエリになります。
ステップ2-抽出式を使用して理論をテストする
CREATE TABLE PlayerJ (
Id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
Data TEXT NOT NULL
);
CREATE INDEX PlayerJ_FirstName ON PlayerJ (
JSON_EXTRACT(Data, '$.FirstName') ASC,
JSON_EXTRACT(Data, '$.LastName') ASC
);
EXPLAIN QUERY PLAN SELECT
JSON_EXTRACT(Data, '$.FirstName') AS FirstName,
JSON_EXTRACT(Data, '$.LastName') AS LastName
FROM
PlayerJ
WHERE
LENGTH(LastName) > 10
ORDER BY
FirstName
LIMIT
10
OFFSET
0
収量
SCAN TABLE PlayerJ USING INDEX PlayerJ_FirstName
これは私が期待したものではありません。クエリプランナーはORDER BY
節がオンJSON_EXTRACT(Data, '$.FirstName')
であることを理解しているようで、適切なインデックスを選択したようです。しかし、それが私の推論が突然終わるところです。ここで何が起こっているのですか?クエリプランナーがこれが前のテストと同じであり、インデックスがカバリングインデックスとして使用されることを理解することを期待していました。しかし、そうではありません。
何故なの?そして、この2番目のテストは、インデックスに対してのみ実行されるようにどのように変更できますか?