2015-07-10 14 views
7

Sto cercando di capire come l'ordine delle colonne minimizzi le dimensioni della tabella in PostgreSQL.Calcola la dimensione della tupla

Esempio:

CREATE TABLE test (
column_1 int 
,column_2 int 
,column_3 bigint 
,column_4 bigint 
,column_5 text 
,column_6 text 
,column_7 numeric(5,2) 
,column_8 numeric(5,2) 
,column_9 timestamp 
,column_10 boolean 
,column_11 boolean 
); 

INSERT INTO test 
    VALUES(1,1,1,1,'test','test_1',12,12,current_timestamp,true,false); 

SELECT pg_column_size(test.*) FROM test; 

pg_column_size 
---------------- 
     82 
    (1 row) 

Il formato tupla:

23 byte overhead tupla intestazione + 1 byte per NULL bitmap, quindi:

24 + 4 + 4 + 8 + 8 + 5 + 7 + 5 + 5 + 8 + 1 + 1 = 80 ma la dimensione effettiva della tupla è 82.

Esiste un sovraccarico extra di 2 byte?

ho capito l'esempio riportato sopra sotto il collegamento:
Calculating and saving space in PostgreSQL

Se togliamo l'column_8 numeric(5,2) quindi anche la dimensione tupla rimane la stessa, cioè: 82.

ho riordinare la tabella per minimizzare la dimensioni tuple e dà 80.

CREATE TABLE test (
column_3 bigint 
,column_4 bigint 
,column_9 timestamp 
,column_1 int 
,column_2 int 
,column_10 boolean 
,column_11 boolean 
,column_7 numeric(5,2) 
,column_8 numeric(5,2) 
,column_5 text 
,column_6 text); 

INSERT INTO test 
    VALUES(1,1,current_timestamp,1,1,true,false,12,12,'test','test_1'); 

SELECT pg_column_size(test) FROM test; 

pg_column_size 
---------------- 
     80 

c'è qualche suggerimento per ordine di colonne in PostgreSQL?

risposta

6

Si sono persi altri 2 byte di riempimento prima dello column_9 timestamp, che deve essere avviato a un multiplo di 8 byte.

24+4+4+8+8+5+7+5+5+8+1+1=80 but the actual tuple size is 82. 
------------------^ <----- 2 bytes of padding here 

Questo è anche il motivo per questo:

Se togliamo il column_8 numeric(5,2) poi anche la dimensione tupla rimane la stessa, vale a dire: 82.

Dopo estraendo quella colonna che occupa 5 byte si ottengono 7 byte di padding nello stesso punto - il caso peggiore.

noti inoltre che questa riga effettivamente occupa 88 byte sul disco, perché l'intestazione tupla della prossima tupla viene allineato a sinistra (inizia ad un multiplo di MAXALIGN, tipicamente 8 byte).

La riga modificata termina con un multiplo di 8 byte, non richiede ulteriore riempimento e richiede solo 80 byte.

Entrambi hanno bisogno di altri 4 byte per il puntatore a tupla nell'intestazione della pagina, però.

È un gioco di "colonne tetris", le cui basi sembrano aver già capito. In genere non guadagnerai molto, non pensarci troppo. Ci sono casi estremi, però. Valori nulli cambiano il gioco per riga.

È necessario conoscere i requisiti di dimensione, allineamento e riempimento per ciascun tipo di dati e le regole speciali per la bitmap NULL.

risposta correlati con calcolo dettagliate dba.SE:

+0

I tipi di dimensione fissa deve essere posto come 8-byte prima poi 4- byte quindi 2 byte e quindi 1 byte. Che dire di tipo di dimensione variabile come char (n), varchar (n), testo, numerico (p, s). Penso che sia numerico (p, s), char (n), varchar (n) e poi testo. La mia comprensione è corretta? – user3756488

+0

@ user3756488: È possibile combinare tipi di dimensioni variabili che non devono essere allineati liberamente (scegliere un ordine significativo senza tenere conto della memorizzazione). Solo i tipi che devono essere allineati fanno la differenza in questo allineamento potrebbe richiedere il riempimento. Aiuta anche le prestazioni (non la memorizzazione) un pochino per avere colonne a lunghezza fissa, non null prima. –

+0

Grazie Erwin Brandstetter. – user3756488

Problemi correlati