sql >> Database teknologi >  >> RDS >> Mysql

Hvorfor er AVG rækkelængden 4 gange så stor som forventet?

Der er mange grunde til, at den gennemsnitlige rækkestørrelse er høj.

  • Det er en tilnærmelse. (Jeg har fundet ud af, at den typisk er 2x-3x høj.) I et ekstremt tilfælde -- en række i tabellen -- vil den kræve 16384 bytes pr. række. Det er en InnoDB-blok. Antallet af rækker i tabellen er estimeret . Diskpladsen brugt til rækkerne er nøjagtig, men se overheads nedenfor. Den gennemsnitlige rækkestørrelse er kvotienten af ​​disse to.

  • Overhead pr. kolonne -- 1 eller 2 bytes

  • Overhead pr. række -- 20-30 bytes -- til at håndtere transaktioner, finde rækker i en blok osv.

  • Overhead pr. blok -- et vist antal bytes pr. 16 KB blok

  • Overhead til tæsk i et BTree -- min er ca. 1/16 af en blok, max er ca. halvdelen af ​​blokken, gennemsnittet er ca. 30 % efter mange sletninger og/eller tilfældige indsættelser.

  • Overhead til forudtildeling af bidder af diskplads (1MB? 8MB?)

  • Når en tabel vokser fra at passe i én blok, ændres layoutalgoritmen, og procentdelen af ​​overhead stiger midlertidigt.

  • Slettede rækker returnerer ikke deres plads til operativsystemet, så filstørrelsen forbliver konstant, hvilket øger den tilsyneladende rækkestørrelse.

  • Hvis du ikke har en eksplicit PRIMARY KEY eller en UNIQUE nøgle, der kan forfremmes til PK, så er der et utilgængeligt 6-byte felt (pr. række) for PK.

  • Stor TEXT /BLOB og endda VARCHAR er gemt "off-record". Dette komplicerer beregningerne meget. Og det afhænger af hvilken af ​​de 4 ROW_FORMATs du bruger. I nogle tilfælde er der en 20-byte "pointer" for hver sådan celle.

  • FOREIGN KEY begrænsninger tilføjer ikke den nødvendige plads, bortset fra at de kan fremtvinge oprettelsen af ​​et indeks.

  • INDEXes , bortset fra PRIMARY KEY er ikke inkluderet i avg_row_length.

  • PRIMARY KEY normalt involverer meget lidt overhead i dataene BTree. En simpel tommelfingerregel er 1 % overhead (oven på selve kolonnen). Denne overhead er ikke-bladsknuderne i BTree.

  • Mens en InnoDB-transaktion er optaget, holdes eventuelle ændrede rækker på "historiklisten". Dette fører til flere overhead.

  • (Ikke helt relateret). InnoDB's COMPRESSED har problemer -- det giver kun omkring 2x komprimering, i modsætning til typisk tekstkomprimering på 3x. Det koster noget RAM på grund af behovet for at have både de komprimerede og ukomprimerede data i buffer_poolen på samme tid (i det mindste nogle blokke).

SHOW TABLE STATUS og henter fra information_schema.TABLES giver samme data. Der er måder at få nogle på indsigt i dybden af ​​B+Treet for dataene og for hver tabel.




  1. Hvorfor bliver jeg ved med at få en 500 fejl med min PHP?

  2. JQuery Datatable - Opdele enkelt celle i flere kolonner for læsbarhed?

  3. mysql_fetch_array henter ikke alle rækker

  4. Udforskning af de forskellige begrænsninger i SQL Server