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.