LIKE
ohne Platzhalterzeichen entspricht =
. Angenommen, Sie meinten tatsächlich name = 'text'
.
Indizes sind der Schlüssel zur Leistung.
Testaufbau
CREATE TABLE image (
image_id serial PRIMARY KEY
, group_id int NOT NULL
, name text NOT NULL
);
Idealerweise erstellen Sie zwei Indizes (zusätzlich zum Primärschlüssel):
CREATE INDEX image_name_grp_idx ON image (name, group_id);
CREATE INDEX image_grp_idx ON image (group_id);
Die zweite darf je nach Datenverteilung und anderen Details nicht erforderlich sein. Erklärung hier:
- Ist ein zusammengesetzter Index auch gut für Abfragen im ersten Feld?
Abfrage
Dies sollte so schnellstmöglich sein Abfrage für Ihren Fall:
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-Geige.
Das LIMIT
Klausel gilt für die gesamte Abfrage. Postgres ist schlau genug, nicht auszuführen spätere Abschnitte von UNION ALL
sobald es genügend Zeilen gefunden hat, um das LIMIT
zu erfüllen . Folglich für eine Übereinstimmung in der ersten SELECT
der Abfrage, die Ausgabe von EXPLAIN ANALYZE
sieht so aus (nach rechts scrollen! ):
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
Fettdruck von mir.
Tut nicht Fügen Sie einen ORDER BY
hinzu Klausel , würde dies den Effekt aufheben. Dann müsste Postgres alle Zeilen berücksichtigen, bevor es die oberste Zeile zurückgibt.
Abschlussfragen
Gibt es dafür eine generische Lösung?
Das ist die generische Lösung. Fügen Sie so viele SELECT
hinzu Aussagen, wie Sie wollen.
Natürlich wäre es praktisch, wenn das Suchergebnis nach Relevanz sortiert wäre.
Es gibt nur eine Zeile im Ergebnis mit LIMIT 1
. Art der Leersortierung.