LIKE
ワイルドカード文字なしは、=
と同等です。 。あなたが実際にname = 'text'
を意味していると仮定します 。
インデックス パフォーマンスの鍵です。
テストセットアップ
CREATE TABLE image (
image_id serial PRIMARY KEY
, group_id int NOT NULL
, name text NOT NULL
);
理想的には、(主キーに加えて)2つのインデックスを作成します。
CREATE INDEX image_name_grp_idx ON image (name, group_id);
CREATE INDEX image_grp_idx ON image (group_id);
2番目の5月 データの配布やその他の詳細によっては、必要ありません。ここでの説明:
- 複合インデックスは、最初のフィールドのクエリにも適していますか?
クエリ
これは可能な限り最速である必要があります ケースのクエリ:
SELECT * FROM image WHERE name = 'name105' AND group_id = 10
UNION ALL
SELECT * FROM image WHERE name = 'name105'
UNION ALL
SELECT * FROM image WHERE group_id = 10
LIMIT 1;
SQLフィドル。
LIMIT
句はクエリ全体に適用されます。 Postgresは実行しないほど賢いです UNION ALL
の後のレッグ LIMIT
を満たすのに十分な行が見つかるとすぐに 。したがって、最初のでの試合の場合 SELECT
クエリのEXPLAIN ANALYZE
の出力 このように見えます( 右にスクロールしてください! ):
Limit (cost=0.00..0.86 rows=1 width=40) (actual time=0.045..0.046 rows=1 loops=1) Buffers: local hit=4 -> Result (cost=0.00..866.59 rows=1002 width=40) (actual time=0.042..0.042 rows=1 loops=1) Buffers: local hit=4 -> Append (cost=0.00..866.59 rows=1002 width=40) (actual time=0.039..0.039 rows=1 loops=1) Buffers: local hit=4 -> Index Scan using image_name_grp_idx on image (cost=0.00..3.76 rows=2 width=40) (actual time=0.035..0.035 rows=1 loops=1) Index Cond: ((name = 'name105'::text) AND (group_id = 10)) Buffers: local hit=4 -> Index Scan using image_name_grp_idx on image (cost=0.00..406.36 rows=500 width=40) (never executed) Index Cond: (name = 'name105'::text) -> Index Scan using image_grp_idx on image (cost=0.00..406.36 rows=500 width=40) (never executed) Index Cond: (group_id = 10) Total runtime: 0.087 ms
大胆な強調鉱山。
しないでください ORDER BY
を追加します 条項 、これは効果を無効にします。次に、Postgresは一番上の行を返す前にすべての行を考慮する必要があります。
最後の質問
そのための一般的な解決策はありますか?
これはです 一般的なソリューション。 SELECT
をできるだけ多く追加します 必要に応じてステートメント。
もちろん、検索結果を関連性で並べ替えると便利です。
LIMIT 1
の結果には1行しかありません 。ボイドの並べ替えの種類。