PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Jak wypróbować wiele opcji SELECT, aż wynik będzie dostępny?

LIKE bez znaku wieloznacznego jest równoważne = . Zakładając, że rzeczywiście miałeś na myśli name = 'text' .

Indeksy są kluczem do wydajności.

Konfiguracja testowa

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

Najlepiej, jeśli utworzysz dwa indeksy (oprócz klucza podstawowego):

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

Drugi może nie być konieczne, w zależności od dystrybucji danych i innych szczegółów. Wyjaśnienie tutaj:

  • Czy indeks złożony jest również odpowiedni dla zapytań w pierwszym polu?

Zapytanie

To powinno być najszybsze z możliwych zapytanie dotyczące Twojej sprawy:

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;

Skrzypce SQL.

LIMIT klauzula dotyczy całego zapytania. Postgres jest wystarczająco sprytny, nie uruchamia się późniejsze odnogi UNION ALL jak tylko znajdzie wystarczającą liczbę wierszy, aby spełnić LIMIT . W związku z tym dla dopasowania w pierwszym SELECT zapytania, wyjście EXPLAIN ANALYZE wygląda tak (przewiń w prawo! ):

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

Pogrubiony nacisk na moje.

Nie nie dodaj ORDER BY klauzula , unieważniłoby to skutek. Wtedy Postgres musiałby rozważyć wszystkie wiersze przed zwróceniem górnego wiersza.

Pytania końcowe

Czy istnieje na to ogólne rozwiązanie?

To jest ogólne rozwiązanie. Dodaj tyle SELECT oświadczenia, jak chcesz.

Oczywiście przydałoby się to, gdy wynik wyszukiwania jest sortowany według jego trafności.

W wyniku jest tylko jeden wiersz z LIMIT 1 . Rodzaj sortowania pustych przestrzeni.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Dołącz znak plus/minus do liczby w PostgreSQL

  2. Jak przyspieszyć liczenie wierszy w tabeli PostgreSQL?

  3. Dynamiczna funkcja zapytań Postgres

  4. Koszt bezpłatnej reklamy PostgreSQL

  5. Klauzula SQL Between z kolumnami stringów