Come ottimizzare le tabelle InnoDB in MySQL


8

Ho studiato come ottimizzare solo le tabelle frammentate in MySQL e ho esaminato questo post sull'ottimizzazione delle tabelle . Fondamentalmente esegue una query sul database information_schema per qualsiasi tabella con data_free > 0e crea un'istruzione SQL OPTIMIZEsolo per quelle tabelle. Ho eseguito questa query e identificato 148 tabelle per l'ottimizzazione. Tutte le tabelle identificate sono tabelle InnoDB. Dopo aver eseguito lo script SQL di ottimizzazione risultante, ho eseguito nuovamente lo script originale per identificare le tabelle frammentate e ha restituito le stesse tabelle esatte durante il primo passaggio.

Ho visto messaggi contrastanti riguardanti le tabelle InnoDB e il OPTIMIZEcomando. Alcuni sostengono che OPTIMIZEnon funzionerà con le tabelle InnoDB e che è necessario eseguirlo ALTER TABLE table_name ENGINE=INNODB. Altri dicono che in OPTIMIZErealtà chiama il ALTER TABLEcomando quando si esegue su tabelle InnoDB. Con questo in mente, ho eseguito il ALTER TABLEcomando su una delle tabelle InnoDB identificate come frammentate ( data_free > 0) e data_freeho scoperto che in seguito non è cambiato. È ancora maggiore di 0. Ho anche riavviato MySQL e l'ho controllato solo per trovare gli stessi risultati.

Ora, abbiamo diversi server che eseguono MySQL 5.5.29 nella nostra organizzazione e ho eseguito una query su tutti loro per identificare qualsiasi tabella InnoDB con DATA_FREE=0 or NULLe nessuno è stato restituito. Sono tutti maggiori di zero.

Ho anche eseguito il OPTIMIZEcomando su alcune MyISAMtabelle in cui DATA_FREEera maggiore di zero e in seguito ho verificato che fosse zero.

Qualcuno può far luce su questo per me? Qual è il metodo corretto per rimuovere la frammentazione dalle tabelle InnoDB? Qual è il metodo corretto per determinare le tabelle frammentate di InnoDB?

Grazie

Risposte:


9

Suppongo che stai usando innodb_file_per_tableper questa risposta.

C'è più di un significato nella "frammentazione di InnoDB":

  1. .ibd il file è frammentato ed è molto grande mentre il set di dati è piccolo
  2. Le pagine dell'indice sono frammentate in quanto ci sono troppe pagine per contenere pochi dati, nel qual caso potrebbero essere unite.

Si prega di considerare questo post che ho scritto qualche tempo fa: mostra come dopo aver eliminato molte righe da una tabella di grandi dimensioni, il file di dati è frammentato (cioè è molto grande nel filesystem - è un problema noto che questi file non si riducono mai di dimensioni). Eppure gli indici non sono stati frammentati alla fine della cancellazione: questo perché InnoDB unisce correttamente le pagine man mano che diventano vuote.

Il OPTIMIZEcomando infatti non si applica su InnoDB. Quello che fa è ricostruire la tabella (esattamente come una ALTER). Guarda questo:

mysql [localhost] {msandbox} (test) > create table t(id int) engine=innodb;

mysql [localhost] {msandbox} (test) > optimize table t;
+--------+----------+----------+-------------------------------------------------------------------+
| Table  | Op       | Msg_type | Msg_text                                                          |
+--------+----------+----------+-------------------------------------------------------------------+
| test.t | optimize | note     | Table does not support optimize, doing recreate + analyze instead |
| test.t | optimize | status   | OK                                                                |
+--------+----------+----------+-------------------------------------------------------------------+

Per quanto riguarda DATA_FREE: ti suggerisco di ignorare semplicemente questa variabile. Ad essere sincero, ho lavorato con le tabelle InnoDB per 10anni e non ho mai trovato questo valore molto coerente con nulla.

E ora è il momento della vera discussione: che cosa stai esattamente cercando di raggiungere? A meno che il tuo database non sia completamente obsoleto, ci sarà sempre qualche frammentazione. È naturale il processo di aggiunta, rimozione e aggiornamento delle righe nella tabella.

La frammentazione non è così male: lo spazio libero può essere recuperato da nuovi dati. Se i tuoi tavoli non sono molto grandi, allora dimentica tutto. Per tabelle molto grandi, è possibile guadagnare spazio su disco ottimizzando la tabella. Ma chiediti: quanto tempo la tabella raggiungerebbe la stessa frammentazione? Un'ora? Un giorno? Una settimana? IMHO in tutti questi casi è inutile ottimizzare la tabella.

Tuttavia, se una tabella di grandi dimensioni viene eliminata in modo massiccio dai dati, che non dovrebbe restituire, sono tutto per ottimizzarli. Supponi di capire di avere alcuni dati ridondanti che rappresentano circa il 30% delle dimensioni della tabella. Certo, sarebbe bello riavere lo spazio su disco.

Conclusione: considerare questi problemi solo con tabelle molto grandi; solo se hai problemi con lo spazio su disco.


Sono d'accordo che data_free non è utile. Conta solo lo spazio in "estensioni libere" per il tablespace, che è una terribile metrica per il calcolo della frammentazione. Penso che se non lo stai usando innodb_file_per_tablemostrerai lo stesso valore per ogni tabella nel tablespace condiviso.
Jeremycole,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.