Różnica PostgreSQL między VACUUM FULL a CLUSTER

13

Mam tabelę z 200 GB wielkości zajmowaną przez dane i 180 GB wielkości przez 6 indeksów na niej. Jest nadęty w 30%, więc chcę odzyskać zajmowane przez niego niechciane miejsce. Jest skupiony na job_id_idindeksie x.

Czy więc, aby odzyskać miejsce, muszę użyć clusterpolecenia lub vacuum fullpolecenia?

  1. Jaka jest różnica między tymi dwoma poleceniami?

  2. Czy vacuum fullkolejność według jakiejś kolumny jest taka sama jak clusterpolecenie?

  3. Czy indeks jest odtwarzany w obu poleceniach?

  4. W moim przypadku który będzie szybszy?

Wersja bazy danych PostgreSQL to 9.1

Arun P.
źródło
1
Tak, indeksy zostaną odtworzone. Myślę, że to, co jest szybsze, zależy od kilku rzeczy. Ale jedno jest pewne: nie ma to jak „odkurzyć pełne zamówienie według jakiejś kolumny”.
dezso
1
Wspomnę też, że VACUUM nie może działać w ramach transakcji, co w wielu przypadkach czyni CLUSTER lepszą alternatywą (a czasem jedyną alternatywą), która daje podobne wyniki.
o

Odpowiedzi:

8

Aby to sprawdzić CLUSTER, wziąłem tabelę z mojego wcześniejszego eksperymentu, która zawierała pierwsze 10 milionów dodatnich liczb całkowitych. Usunąłem już niektóre wiersze i jest też inna kolumna, ale wpływają one tylko na rzeczywisty rozmiar tabeli, więc nie jest to takie interesujące.

Po pierwsze, po uruchomieniu VACUUM FULLna stole fka, wziąłem jego rozmiar:

\dt+ fka
                    List of relations
 Schema | Name | Type  |  Owner   |  Size  | Description 
--------+------+-------+----------+--------+-------------
 public | fka  | table | test     | 338 MB | 

Zobaczmy więc fizyczną kolejność danych od samego początku tabeli:

SELECT *, ctid FROM fka ORDER BY ctid LIMIT 5;

 id  | col1 |  ctid   
-----+------+---------
   2 | 2    | (0,1)
   3 | 3    | (0,2)
   4 | 4    | (0,3)
   5 | 5    | (0,4)
   6 | 6    | (0,5)

Teraz usuńmy niektóre wiersze:

DELETE FROM fka WHERE id % 10 = 5;
--DELETE 1000000

Po tym raportowany rozmiar tabeli nie zmienił się. Zobaczmy teraz, co CLUSTERrobi:

CLUSTER fka USING fka_pkey;

SELECT *, ctid FROM fka ORDER BY ctid LIMIT 5;

 id  | col1 |  ctid   
-----+------+---------
   2 | 2    | (0,1)
   3 | 3    | (0,2)
   4 | 4    | (0,3)
   6 | 6    | (0,4)
   7 | 7    | (0,5)

Po operacji rozmiar tabeli zmienił się z 338 na 296 MB. Z ctidkolumny, która opisuje fizyczne miejsce krotki na stronie, widać również, że nie ma przerwy w miejscu, w którym id = 5kiedyś było dopasowanie wierszy .

Po zmianie kolejności krotek indeksy powinny zostać odtworzone, aby wskazywały właściwe miejsca.

Różnica wygląda na to, że VACUUM FULLnie porządkuje wierszy. O ile mi wiadomo, istnieje pewna różnica w mechanizmie używanym przez te dwa polecenia, ale z praktycznego punktu widzenia wydaje się, że jest to główna (jedyna?) Różnica.

dezso
źródło
Nie byłem pewien, co to za ctidkolumna. Okazuje się, że jest to kolumna systemowa opisująca fizyczną lokalizację wiersza w tabeli. postgresql.org/docs/current/ddl-system-columns.html
Gajus
8

VACUUM FULLprzepisuje całą zawartość tabeli do nowego pliku na dysku bez dodatkowego miejsca, umożliwiając zwrot niewykorzystanego miejsca do systemu operacyjnego. Ta metoda wymaga również dodatkowego miejsca na dysku, ponieważ zapisuje nową kopię tabeli i nie zwalnia starej kopii, dopóki operacja nie zostanie zakończona. Zwykle należy tego używać tylko wtedy, gdy znaczna ilość miejsca wymaga odzyskania z wnętrza stołu.

http://www.postgresql.org/docs/9.1/static/sql-vacuum.html

CLUSTERinstruuje PostgreSQL do zgrupowania tabeli określonej przez nazwa_tabeli na podstawie indeksu określonego przez nazwa_indeksu. Indeks musi być już zdefiniowany dla nazwa_tabeli. Tabela jest klastrowana, a jej fizyczna kolejność jest zmieniana na podstawie informacji o indeksie i zostaje na niej uzyskana blokada ACCESS EXCLUSIVE.

http://www.postgresql.org/docs/9.1/static/sql-cluster.html

również ciekawe: is-a-reindex-Required-after-cluster

Ale może wszystko, czego potrzebujesz, to prosta, REINDEXktóra odbudowuje indeks na podstawie danych przechowywanych w tabeli indeksu, zastępując starą kopię indeksu.

http://www.postgresql.org/docs/9.1/static/sql-reindex.html

kpt
źródło
1
Łał! Dobra wskazówka na temat REINDEX! Zmniejszyłem kilka tabel zarówno przez VACUUM, jak i CLUSTER (próbując porównać czasy i wpływ na to, jak to zrobić na żywo), a teraz moje największe obiekty to tak naprawdę indeksy.
mike