Ho fatto molte ricerche su come mantenere gli indici in MySQL per prevenire la frammentazione e ottimizzare in qualche modo l'esecuzione di alcune query.
Conosco quella formula che calcola il rapporto tra lo spazio massimo disponibile per una tabella VS lo spazio utilizzato da dati e indici.
Tuttavia le mie domande principali sono ancora senza risposta. Forse questo è dovuto al fatto che ho familiarità con la manutenzione dell'indice in SQL Server e tendo a pensare che in MySQL dovrebbe essere in qualche modo simile.
In SQL Server, è possibile disporre di più indici e ognuno di essi può avere diversi livelli di frammentazione. Quindi puoi prenderne uno ed eseguire un'operazione 'RIORGANIZZA' o 'RICOSTRUISCI' in quel particolare indice, senza influire sul resto.
Per quanto ne so, non esiste una "frammentazione di tabelle" in quanto tale e SQL Server non fornisce alcun strumento per correggere la "frammentazione di tabelle". Ciò che fornisce sono strumenti per controllare la frammentazione dell'indice (intesa come il rapporto tra il numero di pagine utilizzate da un indice VS la pienezza di quella pagina e la contiguità), nonché la frammentazione interna ed esterna.
Tutto ciò è abbastanza semplice da capire, almeno per me.
Ora, quando arriva il turno di mantenere gli indici in MySQL, esiste solo il concetto di "frammentazione della tabella", come menzionato sopra.
Una tabella in MySQL può avere diversi indici, ma quando controllo il "rapporto di frammentazione" con quella formula famosa, non vedo la frammentazione di ciascun indice, ma la tabella nel suo insieme.
Quando voglio ottimizzare gli indici in MySQL, non scelgo un indice particolare su cui operare (come in SQL Server). Invece, eseguo un'operazione 'OTTIMIZZA' in tutta la tabella, che presumibilmente influenza tutti gli indici.
Quando la tabella è ottimizzata in MySQL, il rapporto tra lo spazio utilizzato da dati + indici VS lo spazio complessivo viene ridotto, il che suggerisce una sorta di riorganizzazione fisica nel disco rigido, che si traduce in una riduzione dello spazio fisico. Tuttavia, la frammentazione dell'indice non riguarda solo lo spazio fisico, ma la struttura dell'albero che è stata modificata nel tempo a causa di inserimenti e aggiornamenti.
Alla fine ho ottenuto un tavolo in InnoDB / MySQL. Quella tabella ha 3 milioni di record, 105 colonne e 55 indici. Sono 1,5 GB esclusi gli indici, che sono 2,1 GB.
Quella tabella viene colpita migliaia di volte ogni giorno per l'aggiornamento, l'inserimento (in realtà non eliminiamo i record).
Quella tabella è stata creata anni dopo e so con certezza che nessuno mantiene indici di sorta.
Mi aspettavo di trovare un'enorme frammentazione lì, ma quando eseguo il calcolo della frammentazione come prescritto
free_space / (data_length + index_length)
risulta che ho solo una frammentazione dello 0,2%. IMHO che è abbastanza irrealistico.
Quindi le grandi domande sono:
- Come posso verificare la frammentazione di un determinato indice in MySQL, non la tabella nel suo insieme
- OPTIMIZE TABLE risolve effettivamente la frammentazione interna / esterna di un indice come in SQL Server?
- Quando ottimizzo una tabella in MySQL, in realtà ricostruisce tutti gli indici sulla tabella?
- È realistico pensare che ridurre lo spazio fisico di un indice (senza ricostruire l'albero stesso) si traduca effettivamente in una prestazione migliore?