sql >> Databasteknik >  >> RDS >> Mysql

Varför är AVG-radlängden 4 gånger så stor som förväntat?

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 en UNIQUE 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 med VARCHAR lagras "off-record". Detta komplicerar beräkningarna mycket. Och det beror på vilken av de fyra ROW_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 än PRIMARY 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.




  1. CakePHP 3:Bästa praxis för tillfälliga SQL-tabeller

  2. Vad är det bästa sättet att infoga flera rader i en mysql-databas med php?

  3. mysql räknas endast för distinkta värden i den förenade frågan

  4. Hur återställer man stoppord i MYSQL?