Det finns många anledningar till att den genomsnittliga radstorleken är hög.
-
Det är en uppskattning. (Jag har upptäckt att den vanligtvis är 2x-3x hög.) I ett extremfall -- en rad i tabellen -- kommer den att göra anspråk på 16384 byte per rad. Det är ett InnoDB-block. Antalet rader i tabellen är uppskattat . Diskutrymmet som används för raderna är exakt, men se omkostnader nedan. Den genomsnittliga radstorleken är kvoten av dessa två.
-
Overhead per kolumn -- 1 eller 2 byte
-
Overhead per rad -- 20-30 byte -- för att hantera transaktioner, hitta rader i ett block, etc.
-
Overhead per block -- något antal byte per 16KB block
-
Overhead för att slå i ett BTree -- min är cirka 1/16 av ett block, max är cirka halva blocket, genomsnittet är cirka 30 % efter många raderingar och/eller slumpmässiga infogningar.
-
Overhead för förallokering av bitar av diskutrymme (1MB? 8MB?)
-
När en tabell växer från att passa i ett block, ändras layoutalgoritmen och procentandelen av overhead ökar tillfälligt.
-
Raderade rader returnerar inte sitt utrymme till operativsystemet, så filstorleken förblir konstant, vilket ökar den skenbara radstorlek.
-
Om du inte har en explicit
PRIMARY KEY
eller enUNIQUE
nyckel som kan flyttas upp till PK, så finns det ett otillgängligt 6-byte fält (per rad) för PK. -
Stor
TEXT
/BLOB
och till och medVARCHAR
lagras "off-record". Detta komplicerar beräkningarna mycket. Och det beror på vilken av de fyraROW_FORMATs
du använder. I vissa fall finns det en 20-byte "pekare" för varje sådan cell. -
FOREIGN KEY
begränsningar lägger inte till det utrymme som krävs, förutom att de kan tvinga fram skapandet av ett index. -
INDEXes
, annat änPRIMARY KEY
ingår inte i avg_row_length. -
PRIMARY KEY
vanligtvis involverar mycket lite overhead i data BTree. En enkel tumregel är 1 % overhead (överst på själva kolumnen). Denna overhead är de icke-bladiga noderna i BTree. -
Medan en InnoDB-transaktion är upptagen, hålls alla modifierade rader kvar i "historiklistan". Detta leder till mer omkostnader.
-
(Inte helt relaterat). InnoDB:s
COMPRESSED
har problem -- det ger bara cirka 2x komprimering, till skillnad från vanlig textkomprimering på 3x. Det kostar lite RAM-minne på grund av att man måste ha både komprimerad och okomprimerad data i buffer_poolen samtidigt (för åtminstone några block).
SHOW TABLE STATUS
och hämtar från information_schema.TABLES
ger samma data. Det finns sätt att få några insikt i djupet av B+Treet för data och för varje tabell.