LIKE
tanpa karakter wildcard sama dengan =
. Dengan asumsi Anda benar-benar bermaksud name = 'text'
.
Indeks adalah kunci kinerja.
Pengaturan pengujian
CREATE TABLE image (
image_id serial PRIMARY KEY
, group_id int NOT NULL
, name text NOT NULL
);
Idealnya, Anda membuat dua indeks (selain kunci utama):
CREATE INDEX image_name_grp_idx ON image (name, group_id);
CREATE INDEX image_grp_idx ON image (group_id);
Yang kedua mungkin tidak perlu, tergantung pada distribusi data dan detail lainnya. Penjelasannya disini:
- Apakah indeks komposit juga bagus untuk kueri di bidang pertama?
Kueri
Ini harus menjadi secepat mungkin kueri untuk kasus Anda:
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 Fiddle.
LIMIT
klausa berlaku untuk seluruh kueri. Postgres cukup pintar untuk tidak mengeksekusi kaki berikutnya dari UNION ALL
segera setelah menemukan baris yang cukup untuk memenuhi LIMIT
. Akibatnya, untuk pertandingan di pertama SELECT
dari kueri, output dari EXPLAIN ANALYZE
terlihat seperti ini (gulir ke kanan! ):
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
Penekanan saya yang berani.
Jangan jangan tambahkan ORDER BY
klausa , ini akan membatalkan efeknya. Maka Postgres harus mempertimbangkan semua baris sebelum mengembalikan baris teratas.
Pertanyaan terakhir
Apakah ada solusi umum untuk itu?
Ini adalah solusi generik. Tambahkan sebanyak SELECT
pernyataan yang Anda inginkan.
Tentu saja akan berguna jika hasil penelusuran diurutkan berdasarkan relevansinya.
Hanya ada satu baris dalam hasil dengan LIMIT 1
. Jenis pengurutan rongga.