SQLite3はjson_extract式でカバリングインデックスを使用していません


8

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番目のテストは、インデックスに対してのみ実行されるようにどのように変更できますか?

回答:


2

ドキュメントは言います:

SQLiteクエリプランナーは、インデックス付けされた式がクエリのWHERE句またはORDER BY句にある場合、式でのインデックスの使用を検討します。

そのため、SELECT句の式は式インデックスを使用しません。

カバリングインデックスを使用しても、検索/並べ替えに通常のインデックスを使用するよりも、通常のインデックスを使用するよりも改善が少ないため、この最適化は(まだ?)式インデックスに対して実装されていません。


SELECTフィールドでエイリアスを作成しただけなので、WHEREやORDER BYステートメントでJSON_EXTRACT式を使用することは同等です。エイリアスの代わりにJSON_EXTRACTを使用するようにクエリを書き換えても、別の結果は得られません。
穂月
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.