LIKE
uden jokertegn svarer til =
. Forudsat at du faktisk mente name = 'text'
.
Indekser er nøglen til ydeevne.
Test opsætning
CREATE TABLE image (
image_id serial PRIMARY KEY
, group_id int NOT NULL
, name text NOT NULL
);
Ideelt set opretter du to indekser (ud over den primære nøgle):
CREATE INDEX image_name_grp_idx ON image (name, group_id);
CREATE INDEX image_grp_idx ON image (group_id);
Den anden kan ikke være nødvendigt, afhængigt af datadistribution og andre detaljer. Forklaring her:
- Er et sammensat indeks også godt til forespørgsler i det første felt?
Forespørgsel
Dette bør være den hurtigst mulige forespørgsel til din sag:
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
klausulen gælder for hele forespørgslen. Postgres er smart nok ikke at udføre senere ben af UNION ALL
så snart den har fundet nok rækker til at opfylde LIMIT
. Derfor til en kamp i den første SELECT
af forespørgslen, outputtet af EXPLAIN ANALYZE
ser sådan ud (rul til højre! ):
Fed fremhævelse mine.
Gør det ikke tilføje en ORDER BY
klausul , ville dette annullere effekten. Så skulle Postgres overveje alle rækker, før de returnerede den øverste række.
Sidste spørgsmål
Er der en generisk løsning til det?
Dette er den generiske løsning. Tilføj så mange SELECT
udsagn, som du ønsker.
Det ville selvfølgelig være nyttigt, når søgeresultatet er sorteret efter dets relevans.
Der er kun én række i resultatet med LIMIT 1
. En slags tomrumssortering.