Dlaczego SELECT * jest znacznie szybszy niż wybieranie wszystkich kolumn (w innej kolejności kolumn) według nazwy?

12

Na stole z kolumnami a, b, c, d, e, f, g, h, i, j, k otrzymuję:

select * from misty order by a limit 25;
Time: 302.068 ms

I:

select c,b,j,k,a,d,i,g,f,e,h from misty order by a limit 25;
Time: 1258.451 ms

Czy istnieje sposób na szybkie dokonanie wyboru według kolumny?

Aktualizacja:

Brak indeksu w tabeli, nowo utworzony

Oto ANALIZA WYJAŚNIENIA, nie wydaje się zbyt pomocna:

explain analyze select * from misty order by a limit 25;

Limit  (cost=43994.40..43994.46 rows=25 width=190) (actual time=404.958..404.971 rows=25 loops=1)
->  Sort  (cost=43994.40..45731.11 rows=694686 width=190) (actual time=404.957..404.963 rows=25 loops=1)
     Sort Key: a
     Sort Method: top-N heapsort  Memory: 28kB
     ->  Seq Scan on misty  (cost=0.00..24390.86 rows=694686 width=190) (actual time=0.013..170.945 rows=694686 loops=1)
Total runtime: 405.019 ms
(6 rows)

I:

explain analyze select c,b,j,k,a,d,i,g,f,e,h from misty order by a limit 25;

Limit  (cost=43994.40..43994.46 rows=25 width=190) (actual time=1371.735..1371.745 rows=25 loops=1)
->  Sort  (cost=43994.40..45731.11 rows=694686 width=190) (actual time=1371.733..1371.736 rows=25 loops=1)
     Sort Key: a
     Sort Method: top-N heapsort  Memory: 28kB
     ->  Seq Scan on misty  (cost=0.00..24390.86 rows=694686 width=190) (actual time=0.015..516.355 rows=694686 loops=1)
Total runtime: 1371.797 ms
(6 rows)
Evgeny
źródło
Czy kolumna jest indeksowana? Czy możesz opublikować wyjaśnienie analizy?
user_0
1
Musisz być ostrożny, dokonując dwóch wyborów z rzędu i porównując czasy. Dane w pamięci podręcznej drugiego zapytania mogą uwzględniać różnicę czasów.
Walter Mitty,
1
Widzę także różnice, choć nie tak wyraźne. Moja tabela ma wiersze = 514431 szerokość = 215, a ja otrzymuję około 1,5 s dla select *przypadku i około 2,2 s dla wyboru z kolumnami wymienionymi w innej kolejności .
Colin 't Hart,
Jeśli wymienię wszystkie kolumny w tej samej kolejności, jak zdefiniowano w tabeli, otrzymam w przybliżeniu te same czasy, jak gdybym select *.
Colin 't Hart
2
Tytuł wprowadza w błąd. Pytanie naprawdę brzmi, dlaczego czas trwania sortowania zależy od kolejności kolumn wyjściowych.
Daniel Vérité

Odpowiedzi:

12

Zostało to wysłane na listę mailingową pgsql-hackers i tam starałem się w skrócie odpowiedzieć. Wydaje się, że jeśli lista docelowa (określone kolumny) dokładnie odpowiada deskryptorowi krotki relacji, to znaczy zarówno pod względem liczby kolumn, jak i kolejności, wówczas skan bazowy może zwrócić krotkę, która jest bezpośrednio zużywana przez otaczający węzeł Sortowania. Z drugiej strony, jeśli lista docelowa nie jest zgodna (w kolejności lub liczbie określonych kolumn), skanowanie zwraca formę krotek, która wymaga kroku przygotowania danych Sort do wykonania dodatkowej pracy (konwersja z wewnętrznego formatu krotki na format wykorzystywany bezpośrednio przez kod sortujący).

Nawiasem mówiąc, „*” jest wewnętrznie przekształcane w listę, która (intuicyjnie) pasuje do deskryptora krotki relacji.

EDYCJA: Jeśli spojrzysz na rzeczywiste czasy swojego ostatniego WYKRYWAJ ANALIZĘ, możesz zobaczyć, że to coś więcej niż dawniej. Stało się tak, ponieważ skanowanie wykonało dodatkowy krok projekcji (tj. Konwersję krotki sterty na wartości wewnętrzne [], format nulls []). A ponieważ tak się stało, górny węzeł Sortowania musiał wykonać dodatkową pracę przy inicjalizacji danych, polegającej na przekształceniu go z powrotem do formatu krotki zrozumiałego dla faktycznego etapu sortowania. Widać to po koszcie uruchomienia Sort. W pierwszym przypadku tak się nie dzieje. Oznacza to, że zarówno skanowanie zwraca krotkę taką, jaka jest, a krok inicjalizacji sortowania po prostu ją kopiuje.

amitlan
źródło
@ Colin'tHart, mam nadzieję, że to ma sens.
amitlan
Tak. Miałem nadzieję, że można pominąć ten krok lub go skrócić, używając „przetasowania wskaźnika”, ale jest to dyskusja dla hakerów pgsql.
Colin 't Hart,
Mogą pojawić się pewne ulepszenia na horyzoncie w związku z niedawnym ożywieniem logicznego porządkowania kolumn.
amitlan
Już o tym myślałem i miałem taką nadzieję!
Colin 't Hart,
drogi panie, jeśli potrzebuję tylko kilku kolumn zamiast wszystkich, co będzie szybsze? wybierz * lub wybierz jakieś kolumny? Wielkie dzięki.
sgon00