sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Manera de probar múltiples SELECT hasta que haya un resultado disponible?

LIKE sin carácter comodín es equivalente a = . Asumiendo que realmente quisiste decir name = 'text' .

Índices son la clave del rendimiento.

Configuración de prueba

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

Idealmente, crea dos índices (además de la clave principal):

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

El segundo puede no ser necesario, dependiendo de la distribución de datos y otros detalles. Explicación aquí:

  • ¿Un índice compuesto también es bueno para consultas en el primer campo?

Consulta

Este debería ser el más rápido posible consulta para tu 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;

Violín SQL.

El LIMIT La cláusula se aplica a toda la consulta. Postgres es lo suficientemente inteligente para no ejecutar tramos posteriores de UNION ALL tan pronto como haya encontrado suficientes filas para satisfacer el LIMIT . En consecuencia, para un partido en la primera SELECT de la consulta, la salida de EXPLAIN ANALYZE se ve así (desplazarse hacia la derecha! ):

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

Énfasis en negrita mío.

Hacer no agregar un ORDER BY cláusula , esto anularía el efecto. Entonces Postgres tendría que considerar todas las filas antes de devolver la fila superior.

Preguntas finales

¿Hay una solución genérica para eso?

Esto es la solución genérica. Agregue tantos SELECT declaraciones como quieras.

Por supuesto, sería útil cuando el resultado de la búsqueda se ordene según su relevancia.

Solo hay una fila en el resultado con LIMIT 1 . Tipo de clasificación de vacíos.