sql >> Databasteknik >  >> RDS >> PostgreSQL

Att förstå Postgres radstorlekar

Beräkning av radstorlek är mycket mer komplex än så.

Lagring är vanligtvis uppdelat i 8 kB datasidor . Det finns en liten fast overhead per sida, eventuella rester som inte är tillräckligt stora för att passa en annan tuppel, och ännu viktigare döda rader eller en procentandel som initialt reserverats med FILLFACTOR inställning.

Och det finns ännu mer omkostnader per rad (tuple):en objektidentifierare på 4 byte i början av sidan, HeapTupleHeader på 23 byte och justeringsutfyllnad . Starten av tuppelhuvudet såväl som början av tuppeldata är justerade med en multipel av MAXALIGN , vilket är 8 byte på en typisk 64-bitars maskin. Vissa datatyper kräver justering till nästa multipel av 2, 4 eller 8 byte.

Citerar manualen i systemtabellen pg_tpye :

typalign är justeringen som krävs när du lagrar ett värde av denna typ. Det gäller lagring på disk såväl som de flesta representationer av värdet inuti PostgreSQL. När flera värden lagras i följd, såsom i representationen av en hel rad på disken, infogas utfyllnad före ett datum av denna typ så att det börjar på den specificerade gränsen. Inriktningsreferensen är början på den första referensen i sekvensen.

Möjliga värden är:

  • c =char justering, d.v.s. ingen justering behövs.

  • s =short justering (2 byte på de flesta maskiner).

  • i =int justering (4 byte på de flesta maskiner).

  • d =double justering (8 byte på många maskiner, men inte alla).

Läs om grunderna i manualen här.

Ditt exempel

Detta resulterar i 4 byte utfyllnad efter ditt 3 integer kolumner, eftersom timestamp kolumnen kräver double justering och måste börja med nästa multipel av 8 byte.

Så en rad upptar:

   23   -- heaptupleheader
 +  1   -- padding or NULL bitmap
 + 12   -- 3 * integer (no alignment padding here)
 +  4   -- padding after 3rd integer
 +  8   -- timestamp
 +  0   -- no padding since tuple ends at multiple of MAXALIGN

Plus artikelidentifierare per tuppel i sidhuvudet (som påpekats av @A.H. i kommentaren):

 +  4   -- item identifier in page header
------
 = 52 bytes

Så vi kommer fram till de observerade 52 byte .

Beräkningen pg_relation_size(tbl) / count(*) är en pessimistisk uppskattning. pg_relation_size(tbl) inkluderar bloat (döda rader) och utrymme reserverat av fillfactor , samt overhead per datasida och per tabell. (Och vi nämnde inte ens komprimering för lång varlena data i TOAST-tabeller, eftersom det inte gäller här.)

Du kan installera tilläggsmodulen pgstattuple och anropa SELECT * FROM pgstattuple('tbl_name'); för mer information om bord och tuppelstorlek.

Relaterat:

  • Tabellstorlek med sidlayout
  • Beräkna och spara utrymme i PostgreSQL


  1. ALTER TABLE för att lägga till en sammansatt primärnyckel

  2. Vårdata @CreatedDate-kommentaren fungerar inte för mig

  3. Flytta data från SQL Server till Oracle upprepade gånger

  4. Få en lista över tidszoner som stöds i SQL Server (T-SQL)