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

Kiedy planowane są zapytania (SELECT)?

Nie mogę mówić o samym interfejsie Perla po stronie klienta, ale mogę rzucić trochę światła na stronę serwera PostgreSQL.

PostgreSQL ma przygotowane i nieprzygotowane instrukcje. Nieprzygotowane instrukcje są analizowane, planowane i wykonywane natychmiast. Oni też nie wsparcie podstawiania parametrów. Na zwykłym psql shell możesz pokazać ich plan zapytań w ten sposób:

tmpdb> explain select * from sometable where flag = true;

Z drugiej strony istnieją przygotowane instrukcje:Zazwyczaj są one (patrz „wyjątek” poniżej) analizowane i planowane w jednym kroku, a wykonywane w drugim kroku. Mogą być wielokrotnie wykonywane z różnymi parametrami, ponieważ tak wsparcie podstawiania parametrów. Odpowiednik w psql jest to:

tmpdb> prepare foo as select * from sometable where flag = $1;
tmpdb> explain execute foo(true);

Możesz zauważyć, że plan różni się od planu w nieprzygotowanym oświadczeniu, ponieważ planowanie miało miejsce już w prepare zgodnie z opisem w dokumencie PREPARE :

Oznacza to również, że plan NIE zoptymalizowany dla podstawionych parametrów:W pierwszych przykładach można użyć indeksu dla flag ponieważ PostgreSQL wie, że z miliona wpisów tylko dziesięć ma wartość true . Takie rozumowanie jest niemożliwe, gdy PostgreSQL używa przygotowanej instrukcji. W takim przypadku tworzony jest plan, który będzie działał dla wszystkich możliwych wartości parametrów tak dobrze, jak to tylko możliwe. To może wyklucz wspomniany indeks, ponieważ pobieranie lepszej części pełnej tabeli poprzez dostęp losowy (ze względu na indeks) jest wolniejsze niż zwykłe skanowanie sekwencyjne. PRZYGOTUJ się dokument potwierdza to:

BTW - Jeśli chodzi o buforowanie planu PREPARE dokument ma też coś do powiedzenia:

Ponadto nie ma automatycznego buforowania planu ani buforowania/ponownego wykorzystywania przez wiele połączeń.

WYJĄTEK :Wspomniałem "zazwyczaj". Pokazany psql przykłady nie są tym, czego naprawdę używa adapter klienta, taki jak Perl DBI. Używa pewnego protokołu . Tutaj termin „proste zapytanie” odpowiada „nieprzygotowanemu zapytaniu” w psql , termin „rozszerzone zapytanie „ odpowiada „przygotowanemu zapytaniu” z jednym wyjątkiem:istnieje rozróżnienie między (jednym) „nienazwanym oświadczeniem” a (prawdopodobnie wieloma) „nazwanymi instrukcjami”. Jeśli chodzi o nazwane instrukcje, dokument mówi:

a także:

Tak więc w tym przypadku planowanie odbywa się bez parametrów, jak opisano powyżej dla PREPARE - nic nowego.

Wspomnianym wyjątkiem jest „nienazwana instrukcja”. Dokument mówi:

A oto korzyść:chociaż nienazwana instrukcja jest „przygotowana” (tj. może mieć podstawienie parametrów), może również dostosować plan zapytania do rzeczywistych parametrów.

BTW:Dokładna obsługa nienazwanej instrukcji zmieniała się kilka razy w poprzednich wydaniach serwera PostgreSQL. Jeśli naprawdę chcesz, możesz wyszukać szczegóły w starych dokumentach.

Uzasadnienie - Perl / dowolny klient :

Jak klient jak Perl używa protokołu, to zupełnie inna kwestia. Niektórzy klienci, tacy jak sterownik JDBC dla Javy, w zasadzie mówią:Nawet jeśli programista używa przygotowanej instrukcji, pierwsze pięć (lub więcej) wykonań jest wewnętrznie mapowanych na „proste zapytanie” (tj. skutecznie nieprzygotowane), po czym sterownik przełącza się na „ nazwane oświadczenie".

Klient ma więc następujące możliwości:

  • Wymuś (ponowne) planowanie za każdym razem, używając protokołu „prostego zapytania”.
  • Plan raz, wykonaj wiele razy, używając protokołu „rozszerzonego zapytania” i „nazwanej instrukcji” (plan może być zły, ponieważ planowanie odbywa się bez parametrów).
  • Przetwarzaj raz, zaplanuj każde wykonanie (z aktualną wersją PostgreSQL) używając protokołu "rozszerzonego zapytania" i "instrukcji bez nazwy" i przestrzegając kilku innych rzeczy (podaj kilka parametrów podczas wiadomości "parse")
  • Graj w zupełnie inne sztuczki, takie jak sterownik JDBC.

Co Perl obecnie robi:nie wiem. Ale wspomniany „czerwony śledź” nie jest mało prawdopodobny.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak mogę uzyskać zrzut bazy danych postgres w postaci zwykłego tekstu na heroku?

  2. Czy możliwe jest łatanie ładowanych instrukcji SQL z pliku przy użyciu clojure.java.jdbc?

  3. ODBC v Libpq:biblioteka C dla PostgreSQL

  4. psql.exe - uwierzytelnianie hasłem nie powiodło się w systemie Windows

  5. SQL:Odejmowanie 1 dnia od daty ze znacznika czasu