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 番目は、データの配布やその他の詳細によっては必要ない場合があります。ここでの説明:
クエリ
これは、あなたのケースで可能な限り最速のクエリになるはずです:
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
制限 (コスト=0.00..0.86 行=1 幅=40) (実際の時間=0.045..0.046 行=1 ループ=1)
バッファ: ローカル ヒット = 4
-> 結果 (コスト=0.00..866.59 行=1002 幅=40) (実際の時間=0.042..0.042 行=1 ループ=1)
バッファ: ローカル ヒット = 4
-> 追加 (コスト=0.00..866.59 行=1002 幅=40) (実際の時間=0.039..0.039 行=1 ループ=1)
バッファ: ローカル ヒット = 4
-> イメージで image_name_grp_idx を使用したインデックス スキャン (コスト=0.00..3.76 行=2 幅=40) (実際の時間=0.035..0.035行=1 ループ=1 )
索引条件: ((name = 'name105'::text) AND (group_id = 10))
バッファ: ローカル ヒット = 4
-> イメージの image_name_grp_idx を使用したインデックス スキャン (cost=0.00..406.36 rows=500 width=40) (決して実行されません)
索引条件: (name = 'name105'::text)
-> イメージの image_grp_idx を使用したインデックス スキャン (cost=0.00..406.36 rows=500 width=40) (実行されません)
索引条件: (group_id = 10)
総実行時間: 0.087 ミリ秒
大胆強調鉱山。
句を追加しないでくださいORDER BY
。効果が無効になります。その場合、Postgres は一番上の行を返す前にすべての行を考慮する必要があります。
最終質問
そのための一般的な解決策はありますか?
これが一般的な解決策です。必要な数のステートメントを追加しSELECT
ます。
もちろん、検索結果が関連性でソートされている場合に便利です。
の結果には 1 行しかありませんLIMIT 1
。一種の空隙選別。