Perbedaan PostgreSQL antara VACUUM FULL dan CLUSTER

13

Saya memiliki tabel dengan ukuran 200 GB yang ditempati oleh data dan ukuran 180 GB dengan 6 indeks di atasnya. Ini 30% kembung, jadi saya ingin merebut kembali ruang yang tidak diinginkan yang ditempati olehnya. Itu dikelompokkan pada job_id_idindeks x.

Jadi untuk mendapatkan kembali ruang apakah saya perlu menggunakan clusterperintah atau vacuum fullperintah?

  1. Apa perbedaan antara kedua perintah ini?

  2. Apakah vacuum fullpesanan berdasarkan beberapa kolom sama dengan clusterperintah?

  3. Apakah indeks dibuat kembali di kedua perintah?

  4. Dalam kasus saya yang mana yang akan lebih cepat?

Versi database PostgreSQL adalah 9.1

Arun P
sumber
1
Ya, indeks akan dibuat kembali. Yang saya kira lebih cepat tergantung pada beberapa hal. Tapi satu hal yang pasti: tidak ada yang namanya 'vakum pesanan penuh oleh beberapa kolom'.
dezso
1
Izinkan saya juga menyebutkan bahwa VACUUM tidak dapat berjalan di dalam suatu transaksi yang dalam banyak kasus menjadikan CLUSTER alternatif yang lebih baik (dan terkadang satu-satunya alternatif) yang menghasilkan hasil yang serupa.
o

Jawaban:

8

Untuk memeriksa apa yang CLUSTERterjadi, saya mengambil tabel untuk saya dari percobaan sebelumnya yang pada dasarnya berisi 10 juta bilangan bulat positif pertama. Saya sudah menghapus beberapa baris dan ada kolom lain juga tetapi ini hanya mempengaruhi ukuran tabel yang sebenarnya, jadi tidak begitu menarik.

Pertama, setelah berlari VACUUM FULLdi atas meja fka, saya mengambil ukurannya:

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

Lalu mari kita lihat urutan fisik data dari awal tabel:

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)

Sekarang mari kita hapus beberapa baris:

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

Setelah ini, ukuran tabel yang dilaporkan tidak berubah. Jadi mari kita lihat sekarang apa yang CLUSTERterjadi:

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)

Setelah operasi, ukuran tabel berubah dari 338 menjadi 296 MB. Dari ctidkolom, yang menggambarkan tempat fisik tuple di halaman, Anda juga melihat bahwa tidak ada celah di mana dulu baris yang cocok id = 5.

Saat tupel disusun ulang, indeks seharusnya dibuat ulang sehingga mengarah ke tempat yang benar.

Jadi perbedaannya terlihat bahwa VACUUM FULLtidak memesan baris. Sejauh yang saya tahu, ada beberapa perbedaan dalam mekanisme yang digunakan dua perintah tetapi dari sudut pandang praktis ini tampaknya menjadi perbedaan utama (hanya?).

dezso
sumber
Saya tidak yakin apa ctidkolomnya. Ternyata itu adalah kolom sistem yang menggambarkan lokasi fisik baris dalam tabelnya. postgresql.org/docs/current/ddl-system-columns.html
Gajus
8

VACUUM FULLmenulis ulang seluruh isi tabel menjadi file disk baru tanpa ruang tambahan, memungkinkan ruang yang tidak digunakan dikembalikan ke sistem operasi. Metode ini juga membutuhkan ruang disk tambahan, karena ia menulis salinan tabel baru dan tidak merilis salinan lama sampai operasi selesai. Biasanya ini hanya boleh digunakan ketika sejumlah besar ruang perlu direklamasi dari dalam tabel.

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

CLUSTERmenginstruksikan PostgreSQL untuk mengelompokkan tabel yang ditentukan oleh table_name berdasarkan indeks yang ditentukan oleh index_name. Indeks harus sudah didefinisikan pada table_name. Ketika sebuah tabel dikelompokkan, tabel tersebut disusun secara fisik berdasarkan informasi indeks dan kunci ACCESS EKSKLUSIF diperoleh darinya.

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

juga intresting: is-a-reindex-required-after-cluster

Tapi mungkin yang Anda butuhkan adalah sederhana REINDEXyang membangun kembali indeks menggunakan data yang disimpan dalam tabel indeks, menggantikan salinan lama indeks.

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

cptPH
sumber
1
Wow! Tip yang bagus tentang REINDEX juga! Saya telah menyusut beberapa tabel oleh VACUUM dan CLUSTER (mencoba membandingkan waktu dan dampak untuk melakukannya secara langsung) dan sekarang objek terbesar saya sebenarnya adalah indeks.
mike