5

これは、SQLite が使用可能なインデックスの使用を拒否するのはなぜですか? に関連しています。

データベースを作成するクエリは次のとおりです。

CREATE TABLE foo(id TEXT);
CREATE INDEX `foo.index` ON foo(id);
CREATE TABLE bar(id TEXT);
CREATE INDEX `bar.index` ON bar(id);
CREATE VIEW baz AS SELECT id FROM foo UNION ALL SELECT id FROM bar;
CREATE TABLE bam(ID TEXT, 値 TEXT);

INSERT INTO foo VALUES('123');
INSERT INTO foo VALUES('1123');
INSERT INTO foo VALUES('2123');
INSERT INTO foo VALUES('3123');

INSERT INTO バー VALUES('44123');
INSERT INTO バー VALUES('441123');
INSERT INTO バー VALUES('442123');
INSERT INTO バー VALUES('443123');

の結果EXPLAIN QUERY PLAN SELECT * FROM baz LEFT JOIN bam ON baz.id=bam.id WHERE baz.id IN ('123', '234');は次のとおりです。

SCAN TABLE foo (~1000000 行)
SCAN TABLE バー (~1000000 行)
複合サブクエリ 2 および 3 (UNION ALL)
SCAN サブクエリ 1 (~2000000 行)
EXECUTE LIST サブクエリ 4
AUTOMATIC COVERING INDEX (id=?) を使用してテーブル bam を検索 (~7 行)

編集:興味深いことにEXPLAIN QUERY PLAN SELECT * FROM (SELECT * FROM baz WHERE baz.id IN ('123', '234')) AS t LEFT JOIN bam ON t.id=bam.id ;、インデックスを使用してもインデックスは使用EXPLAIN QUERY PLAN SELECT * FROM baz WHERE baz.id IN ('123', '234');されませんが、使用すると使用されます。何が起こっている?

foo と bar のインデックスを使用しないのはなぜですか?? リンクされた質問で明らかなように、JOINセクションなしでインデックスを使用します。

SQL フィドル: http://sqlfiddle.com/#!7/32af2/14 (WebSQL を使用)

4

3 に答える 3

4

クエリ プランナーは、このインスタンスではインデックスの使用が効率的ではないと判断しています。ただし、次の方法でビューを変更することにより、インデックスの使用を強制することも可能です。

CREATE VIEW baz AS SELECT id FROM foo UNION ALL SELECT id FROM bar ORDER BY id;

このORDER BYステートメントは、インデックス付きフィールドにアクセスするときにインデックスの使用を強制します。

新しいクエリ プランの結果:

EXPLAIN QUERY PLAN SELECT * FROM baz LEFT JOIN bam ON baz.id=bam.id WHERE baz.id IN ('123', '234');

SCAN TABLE foo USING COVERING INDEX foo.index (~4 rows)
SCAN TABLE bar USING COVERING INDEX bar.index (~4 rows)
COMPOUND SUBQUERIES 2 AND 3 (UNION ALL)
SCAN SUBQUERY 1 (~2 rows)
EXECUTE LIST SUBQUERY 4
SEARCH TABLE bam USING INDEX bam.index (id=?) (~1 rows)
于 2013-11-07T19:08:30.873 に答える
0

dbms は結果の一時的なコピーを作成するため、Union All の最適化は非常に困難です。ユニオンオールがどのように実装されているかについてのドキュメントを具体的に見つける必要がありますが、foobar 列で設計することができます。

CREATE TABLE Danny117(id TEXT, mytype TEXT);

INSERT INTO Danny117 VALUES('123', 'foo');
INSERT INTO Danny117 VALUES('1123', 'foo');
INSERT INTO Danny117 VALUES('2123', 'foo');
INSERT INTO Danny117 VALUES('3123', 'foo');

INSERT INTO Danny117 VALUES('44123','bar');
INSERT INTO Danny117 VALUES('441123','bar');
INSERT INTO Danny117 VALUES('442123','bar');
INSERT INTO Danny117 VALUES('443123','bar');

結果として

EXPLAIN QUERY PLAN SELECT Danny117.id, bam.* FROM Danny117 LEFT JOIN bam ON danny117.id=bam.id WHERE danny117.id IN ('123', '234');

幸運を

于 2013-11-05T00:44:45.897 に答える