sql >> Database teknologi >  >> RDS >> PostgreSQL

Måde man prøve flere SELECT'er, indtil et resultat er tilgængeligt?

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! ):

Grænse (pris=0.00..0.86 rækker=1 bredde=40) (faktisk tid=0.045..0.046 rækker=1 sløjfer=1) Buffere:lokalt hit=4 -> Resultat (pris=0.00..866.59 rækker =1002 bredde=40) (faktisk tid=0,042..0.042 rækker=1 sløjfer=1) Buffere:lokalt hit=4 -> Tilføj (pris=0.00..866.59 rækker=1002 bredde=40) (faktisk tid=0.039. .0.039 rækker=1 sløjfer=1) Buffere:lokalt hit=4 -> Indeksscanning ved hjælp af image_name_grp_idx på billedet (pris=0.00..3.76 rækker=2 bredde=40) (faktisk tid=0.035..0.035 rækker=1 sløjfer=1 ) Index Cond:((name ='name105'::text) AND (group_id =10)) Buffere:local hit=4 -> Index Scan vha. image_name_grp_idx på billedet (cost=0.00..406.36 rows=500 width=40) (aldrig udført) Index Cond:(navn ='name105'::text) -> Index Scan ved hjælp af image_grp_idx på billede (cost=0.00..406.36 rows=500 width=40) (aldrig udført) Indekstilstand:(group_id =10) Samlet køretid:0,087 ms

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.



  1. MySQL - Hvordan unpivot kolonner til rækker?

  2. Sådan fungerer WEEKDAY() i MariaDB

  3. Du kan nu bruge Access med Microsoft Azure MFA!

  4. Importer database til MySQL eller MariaDB