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

Modo di provare più SELECT finché non è disponibile un risultato?

LIKE senza carattere jolly equivale a = . Supponendo che tu intenda effettivamente name = 'text' .

Indici sono la chiave delle prestazioni.

Impostazione di prova

CREATE TABLE image (
  image_id serial PRIMARY KEY
, group_id int NOT NULL
, name     text NOT NULL
);

Idealmente, crei due indici (oltre alla chiave primaria):

CREATE INDEX image_name_grp_idx ON image (name, group_id);
CREATE INDEX image_grp_idx ON image (group_id);

Il secondo può non essere necessario, a seconda della distribuzione dei dati e di altri dettagli. Spiegazione qui:

  • Un indice composito va bene anche per le query sul primo campo?

Interrogazione

Questo dovrebbe essere il più veloce possibile richiesta per il tuo caso:

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.

Il LIMIT la clausola si applica all'intera query. Postgres è abbastanza intelligente da non eseguire tappe successive di UNION ALL non appena ha trovato righe sufficienti per soddisfare il LIMIT . Di conseguenza, per una partita nella prima SELECT della query, l'output di EXPLAIN ANALYZE appare così (scorri verso destra! ):

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

Enfasi in grassetto la mia.

Non non aggiungi un ORDER BY clausola , ciò annullerebbe l'effetto. Quindi Postgres dovrebbe considerare tutte le righe prima di restituire la riga superiore.

Domande finali

Esiste una soluzione generica per questo?

Questo è la soluzione generica. Aggiungi tanti SELECT dichiarazioni come vuoi.

Ovviamente sarebbe utile quando il risultato della ricerca è ordinato in base alla sua rilevanza.

C'è solo una riga nel risultato con LIMIT 1 . Tipo di ordinamento dei vuoti.