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

Co dokładnie wyjaśnia PostgreSQL?

Część, którą zawsze uważałem za mylącą, to koszt uruchomienia w porównaniu z całkowitym kosztem. Google to za każdym razem, gdy o tym zapominam, co mnie tu sprowadza, co nie wyjaśnia różnicy, dlatego piszę tę odpowiedź. Oto, czego dowiedziałem się z EXPLAIN Postgresa dokumentację wyjaśnioną tak, jak ją rozumiem.

Oto przykład z aplikacji zarządzającej forum:

EXPLAIN SELECT * FROM post LIMIT 50;

Limit  (cost=0.00..3.39 rows=50 width=422)
  ->  Seq Scan on post  (cost=0.00..15629.12 rows=230412 width=422)

Oto graficzne wyjaśnienie od PgAdmin:

(Gdy używasz PgAdmin, możesz skierować kursor myszy na komponent, aby odczytać szczegóły kosztów).

Koszt jest reprezentowany jako krotka, np. koszt LIMIT to cost=0.00..3.39 i koszt sekwencyjnego skanowania post to cost=0.00..15629.12 . Pierwsza liczba w krotce to koszt uruchomienia a druga liczba to całkowity koszt . Ponieważ użyłem EXPLAIN a nie EXPLAIN ANALYZE , te koszty są szacunkami, a nie rzeczywistymi środkami.

  • Koszt uruchomienia to trudna koncepcja. Reprezentuje nie tylko czas przed uruchomieniem tego komponentu . Reprezentuje czas między rozpoczęciem wykonywania komponentu (odczytywanie danych) a momentem, w którym komponent wyprowadza swój pierwszy wiersz .
  • Całkowity koszt to całkowity czas wykonania komponentu, od momentu rozpoczęcia odczytu danych do zakończenia zapisywania danych wyjściowych.

Jako komplikacja, koszty każdego węzła „nadrzędnego” obejmują koszty jego węzłów podrzędnych. W reprezentacji tekstowej drzewo jest reprezentowane przez wcięcie, np. LIMIT jest węzłem nadrzędnym i Seq Scan jest jego dzieckiem. W reprezentacji PgAdmin strzałki wskazują od dziecka do rodzica — kierunek przepływu danych — co może być sprzeczne z intuicją, jeśli znasz teorię grafów.

Dokumentacja mówi, że koszty obejmują wszystkie węzły podrzędne, ale zauważ, że całkowity koszt rodzica 3.39 jest znacznie mniejszy niż całkowity koszt jego dziecka 15629.12 . Całkowity koszt nie jest uwzględniony, ponieważ komponent taki jak LIMIT nie musi przetwarzać całego swojego wejścia. Zobacz EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000 LIMIT 2; przykład w Postgresie EXPLAIN dokumentacja.

W powyższym przykładzie czas uruchamiania wynosi zero dla obu składników, ponieważ żaden składnik nie musi wykonywać żadnego przetwarzania przed rozpoczęciem zapisywania wierszy:skanowanie sekwencyjne odczytuje pierwszy wiersz tabeli i emituje go. LIMIT odczytuje swój pierwszy wiersz, a następnie go emituje.

Kiedy składnik musiałby wykonać dużo przetwarzania, zanim będzie mógł zacząć wyprowadzać jakiekolwiek wiersze? Istnieje wiele możliwych powodów, ale spójrzmy na jeden jasny przykład. Oto to samo zapytanie co wcześniej, ale teraz zawiera ORDER BY klauzula:

EXPLAIN SELECT * FROM post ORDER BY body LIMIT 50;

Limit  (cost=23283.24..23283.37 rows=50 width=422)
  ->  Sort  (cost=23283.24..23859.27 rows=230412 width=422)
        Sort Key: body
        ->  Seq Scan on post  (cost=0.00..15629.12 rows=230412 width=422)

I graficznie:

Po raz kolejny sekwencyjne skanowanie post nie ma kosztu początkowego:natychmiast rozpoczyna wyprowadzanie wierszy. Ale ten rodzaj ma znaczny koszt początkowy 23283.24 ponieważ musi posortować całą tabelę, zanim wygeneruje nawet pojedynczy wiersz . Całkowity koszt sortowania 23859.27 jest tylko nieznacznie wyższy niż koszt uruchomienia, co odzwierciedla fakt, że po posortowaniu całego zestawu danych posortowane dane mogą być emitowane bardzo szybko.

Zwróć uwagę, że czas uruchamiania LIMIT 23283.24 jest dokładnie równy czasowi uruchomienia danego rodzaju. Nie dzieje się tak, ponieważ LIMIT sam w sobie ma wysoki czas uruchamiania. Sam w sobie ma zerowy czas uruchamiania, ale EXPLAIN zlicza wszystkie koszty dziecka dla każdego rodzica, więc LIMIT czas uruchamiania obejmuje sumę czasów uruchamiania jego elementów potomnych.

Takie zestawienie kosztów może utrudnić zrozumienie kosztu wykonania każdego pojedynczego komponentu. Na przykład nasz LIMIT ma zerowy czas uruchamiania, ale na pierwszy rzut oka nie jest to oczywiste. Z tego powodu kilka innych osób połączyło się z explain.depesz.com, narzędziem stworzonym przez Huberta Lubaczewskiego (aka depesz), które pomaga zrozumieć EXPLAIN poprzez — między innymi — odjęcie kosztów dziecka od kosztów rodziców. W krótkim wpisie na blogu o swoim narzędziu wspomina o innych zawiłościach.



  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 rejestrować zapytania w PostgreSQL

  2. USUŃ KASKADOWE tylko raz

  3. Połącz aplikację na iPhone'a z PostgreSQL za pomocą Libpq

  4. Ograniczenie sprawdzania PostgreSQL dla warunku klucza obcego

  5. Aktualizacja wierszy bazy danych bez blokowania tabeli w PostgreSQL 9.2