回答
Webサイトを参照してuse-the-index-luke.com
いるため、次の章を検討してください。
インデックスの使用、ルーク› Where句›範囲の検索› Greater、Less、BETWEEN
あなたの状況に完全に一致する例があります(2列のインデックス、1つは同等性、もう1つはrangeについてテストされています)、@ ypercubeのアドバイスが正確である理由を説明します(これらの素敵なインデックスグラフィックをさらに使用):
Rule of thumb: index for equality first — then for ranges.
1列だけでも良いですか?
1列のみのクエリに対して何をすべきかは明らかです。これらの関連する質問の下でそれに関する詳細とベンチマーク:
最初に選択性の低い列ですか?
それとは別に、両方の列に等しい条件しかない場合はどうでしょうか?
どうでもいい。実際に重要な独自の条件を受け取る可能性が高い列を最初に配置します。
このデモを検討するか、自分で再現してください。10万行の2列の単純なテーブルを作成します。1つは非常に少数で、もう1つは多くの異なる値を持ちます。
CREATE TEMP TABLE t AS
SELECT (random() * 10000)::int AS lots
, (random() * 4)::int AS few
FROM generate_series (1, 100000);
DELETE FROM t WHERE random() > 0.9; -- create some dead tuples, more "real-life"
ANALYZE t;
SELECT count(distinct lots) -- 9999
, count(distinct few) -- 5
FROM t;
クエリ:
SELECT *
FROM t
WHERE lots = 2345
AND few = 2;
EXPLAIN ANALYZE
出力(キャッシュ効果を除外するためのベスト10):
tのSeqスキャン(コスト= 0.00..5840.84行= 2幅= 8)
(実際の時間= 5.646..15.535行= 2ループ= 1)
フィルター:((lots = 2345)AND(few = 2))
バッファー:ローカルヒット= 443
合計ランタイム:15.557ミリ秒
インデックスを追加して、再テストします。
CREATE INDEX t_lf_idx ON t(lots, few);
tでt_lf_idxを使用したインデックススキャン(コスト= 0.00..3.76行= 2幅= 8)
(実際の時間= 0.008..0.011行= 2ループ= 1)
インデックス条件:((lots = 2345)AND(few = 2))
バッファー:ローカルヒット= 4
合計ランタイム:0.027 ms
他のインデックスを追加して、再テストします。
DROP INDEX t_lf_idx;
CREATE INDEX t_fl_idx ON t(few, lots);
tでt_fl_idxを使用したインデックススキャン(コスト= 0.00..3.74行= 2幅= 8)
(実際の時間= 0.007..0.011行= 2ループ= 1)
インデックス条件:((few = 2)AND(lots = 2345))
バッファー:ローカルヒット= 4
合計ランタイム:0.027 ms