Differenza PostgreSQL tra VACUUM FULL e CLUSTER


13

Ho una tabella con 200 GB di dimensione occupata dai dati e 180 GB di dimensione dai 6 indici su di essa. È gonfiato al 30%, quindi voglio recuperare lo spazio indesiderato occupato da esso. È raggruppato su job_id_idindice x.

Quindi per recuperare lo spazio devo usare il clustercomando o il vacuum fullcomando?

  1. Qual è la differenza tra questi due comandi?

  2. L' vacuum fullordine in base a qualche colonna è uguale al clustercomando?

  3. L'indice viene ricreato in entrambi i comandi?

  4. Nel mio caso quale sarà più veloce?

La versione del database PostgreSQL è 9.1


1
Sì, gli indici verranno ricreati. Il che è più veloce dipende da alcune cose, immagino. Ma una cosa è certa: non esiste nulla di simile al "vuoto di ordine completo per colonna".
dezso,

1
Vorrei anche menzionare che VACUUM non può essere eseguito all'interno di una transazione che in molti casi rende CLUSTER un'alternativa migliore (e talvolta l'unica alternativa) che produce risultati simili.
o

Risposte:


8

Per verificare cosa CLUSTERsuccede, ho preso un tavolo per il mio da un precedente esperimento che sostanzialmente conteneva i primi 10 milioni di numeri interi positivi. Ho già eliminato alcune righe e c'è anche un'altra colonna, ma queste influiscono solo sulla dimensione effettiva della tabella, quindi non è così interessante.

Innanzitutto, avendo eseguito VACUUM FULLsul tavolo fka, ho preso le sue dimensioni:

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

Quindi vediamo l'ordine fisico dei dati fin dall'inizio della tabella:

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)

Ora eliminiamo alcune righe:

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

Successivamente, la dimensione della tabella riportata non è cambiata. Vediamo ora cosa CLUSTERfa:

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)

Dopo l'operazione, le dimensioni della tabella sono cambiate da 338 a 296 MB. Dalla ctidcolonna, che descrive la posizione fisica della tupla nella pagina, puoi anche vedere che non c'era spazio dove si trovava la corrispondenza delle righe id = 5.

Man mano che le tuple venivano riordinate, gli indici avrebbero dovuto essere ricreati in modo che indichino i punti corretti.

Quindi la differenza sembra essere che VACUUM FULLnon ordina le righe. Per quanto ne so, esiste una certa differenza nel meccanismo utilizzato dai due comandi, ma dal punto di vista pratico questa sembra essere la differenza principale (unica?).


Non ero sicuro di quale fosse la ctidcolonna. Si scopre che è una colonna di sistema che descrive la posizione fisica della riga all'interno della sua tabella. postgresql.org/docs/current/ddl-system-columns.html
Gajus

8

VACUUM FULLriscrive l'intero contenuto della tabella in un nuovo file su disco senza spazio aggiuntivo, consentendo allo spazio inutilizzato di essere restituito al sistema operativo. Questo metodo richiede anche spazio su disco aggiuntivo, poiché scrive una nuova copia della tabella e non rilascia la vecchia copia fino al completamento dell'operazione. Di solito questo dovrebbe essere usato solo quando è necessario recuperare una quantità significativa di spazio all'interno della tabella.

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

CLUSTERindica a PostgreSQL di raggruppare la tabella specificata da table_name in base all'indice specificato da index_name. L'indice deve essere già stato definito su table_name. Quando una tabella viene raggruppata, viene riordinata fisicamente in base alle informazioni dell'indice e su di essa viene acquisito un blocco ACCESS EXCLUSIVE.

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

anche interessante: is-a-reindex-richiesto-dopo-cluster

Ma forse tutto ciò che serve è un semplice REINDEXche ricostruisce un indice usando i dati memorizzati nella tabella dell'indice, sostituendo la vecchia copia dell'indice.

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


1
Woah! Un bel consiglio anche su REINDEX! Ho ridotto alcuni tavoli di VACUUM e CLUSTER (cercando di confrontare tempi e impatti per farlo dal vivo) e ora i miei oggetti più grandi sono in realtà indici.
Mike
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.