0

現在、次のように定義しているテーブルがあります。

CREATE TABLE pairs (  
id INTEGER PRIMARY KEY,
p1 INTEGER,
p2 INTEGER,
r  INTEGER,
UNIQUE(p1, p2) ON CONFLICT IGNORE,
FOREIGN KEY (p1) REFERENCES points(id),
FOREIGN KEY (p2) REFERENCES points(id)
)

その後、ギガバイトのデータでいっぱいになります。ここで、次のように多くの選択を行う必要があります。

SELECT id, r FROM pairs WHERE p1 = 666 OR p2 = 666

問題は、この選択を高速化するためにどのインデックスを作成する必要があるかということです。

CREATE INDEX p1_index ON pairs(p1)
CREATE INDEX p2_index ON pairs(p2)

または多分

CREATE UNIQUE INDEX p_index ON pairs(p1, p2)

それとも両方かもしれませんか?(そして彼らのために新しいHDDを購入してください)。UNIQUESQLite3 は、複数の列に対する制約のインデックスを自動的に作成しません。

4

2 に答える 2

2

OR 条件を使用しているため、複数のインデックスを使用します。AND 条件の場合は、複数列のインデックスの方がうまく機能します。

OR 条件の場合: オプティマイザーはインデックスの 1 つを調べ始め、一致するものを見つけて、その行を取得します。もう一方のインデックスは、最初のインデックスと一致しない場合にのみ参照されます。マルチプロセッサ システムでは、両方のインデックスも並行してスキャンされます (スキャンする必要があります)。すごいですよね?

AND 条件の場合: 2 つのインデックスが使用可能な場合、オプティマイザは両方を調べ、2 つのインデックス スキャンの出力をマージしてから、ベース テーブルから結果をフェッチする必要があります。これは高価になる可能性があります。ここでは、複数列のインデックスが最適でした。

ただし、オプティマイザーは、使用可能なテーブルとインデックスの統計に基づいて、別のパスを選択する場合があります。

お役に立てれば。

于 2013-04-07T07:48:16.410 に答える
0

EXPLAIN QUERY PLANを使用して、インデックスが使用されているかどうかを確認します。

例のクエリでは、両方の単一列インデックスが使用されます。

> EXPLAIN QUERY PLAN SELECT id, r FROM pairs WHERE p1 = 666 OR p2 = 666;
0|0|0|SEARCH TABLE pairs USING INDEX p1_index (p1=?) (~10 rows)
0|0|0|SEARCH TABLE pairs USING INDEX p2_index (p2=?) (~10 rows)

単一レコードの検索に両方の列が必要な場合は、複数列インデックス (UNIQUE 制約のために既に持っている) が使用されます。

> EXPLAIN QUERY PLAN SELECT id, r FROM pairs WHERE p1 = 666 AND p2 = 666;
0|0|0|SEARCH TABLE pairs USING INDEX sqlite_autoindex_pairs_1 (p1=? AND p2=?) (~1 rows)

ただし、複数列のインデックスを最初の列の検索に使用することもできます。

> DROP INDEX p1_index;
> EXPLAIN QUERY PLAN SELECT id, r FROM pairs WHERE p1 = 666 OR p2 = 666;
0|0|0|SEARCH TABLE pairs USING INDEX sqlite_autoindex_pairs_1 (p1=?) (~10 rows)
0|0|0|SEARCH TABLE pairs USING INDEX p2_index (p2=?) (~10 rows)

次のドキュメントも参照してください:
Query Optimizer Overview
Query Planning

于 2013-04-07T09:57:53.327 に答える