Il meglio di MyISAM e InnoDB


17

È possibile fare in modo che InnoDB utilizzi gli indici come MyISAM anziché l'indice cluster a causa della limitazione della RAM e di trarre vantaggio dalle prestazioni della concorrenza?

Risposte:


14

Il gen_clust_index (indice cluster) sotto il cofano di InnoDB ospita le voci delle chiavi primarie insieme ai rowid. Ciò che è interessante sull'uso di gen_clust_index è il fatto che qualsiasi indice non univoco creato avrà sempre un rowid corrispondente per gen_clust_index di una tabella. Pertanto, ci sono sempre ricerche a doppio indice, una per l'indice secondario e una per gen_clust_index.

Qualsiasi tentativo di migliorare il layout di una tabella o chiave primaria viene annullato a causa di gen_clust_index, o almeno dei risultati marginali.

ESEMPIO

Alcune persone tentano di ordinare un MyISAM in ordine PRIMARY KEY. Secondo MySQL Database Design and Tuning, paragrafo 7, sotto il sottotitolo "Memorizzazione di una tabella in ordine di indice":

Se si recuperano frequentemente grandi intervalli di dati indicizzati da una tabella o si ordinano costantemente i risultati sulla stessa chiave di indice, è possibile prendere in considerazione l'esecuzione di myisamchk con l'opzione --sort-records. In questo modo, dire a MySQL di ordinare i dati della tabella nello stesso ordine fisico dell'indice e di velocizzare questo tipo di operazioni. In alternativa, è possibile combinare l'istruzione ALTER TABLE con un ORDER BY di una particolare opzione di colonna per ottenere gli stessi risultati.

Concesso, funziona e funziona efficacemente per MyISAM . È possibile eseguire ALTER TABLE ... ORDER BY col1, col2, ..., coln contro InnoDB dove le colonne possono essere o meno quelle del PRIMARY KEY. Questo non produrrà risultati più veloci per InnoDB perché ... esatto ... è necessario consultare gen_clust_index ogni volta.

Alcune persone possono rendere FISSO il formato di riga della tabella usando ALTER TABLE mydb.mytb ROW_FORMAT=Fixed;e possono ottenere un aumento del 20% delle prestazioni di lettura senza altre modifiche. Questo funziona e funziona in modo efficace PER MyISAM . Questo non produrrà risultati più veloci per InnoDB perché ... esatto ... è necessario consultare gen_clust_index ogni volta.

È possibile eseguire le seguenti operazioni su una tabella InnoDB denominata mydb.mytb:

CREATE TABLE mydb.mytc LIKE mydb.mytb;
INSERT INTO mydb.mytc SELECT * FROM mydb.mytb ORDER BY col1,col2,...coln;
ALTER TABLE mydb.mytb RENAME mydb.mytd;
ALTER TABLE mydb.mytc RENAME mydb.mytb;
DROP TABLE mydb.mytd;

Questo metterà la tabella in ordine rowid in gen_clust_index. Questo potrebbe produrre risultati marginali per InnoDB nella migliore delle ipotesi perché ... esatto ... è necessario consultare gen_clust_index ogni volta.

Ora, diventiamo un po 'ridicoli. Esiste un'interfaccia NoSQL per interrogare (solo SELEZIONA) MyISAM e InnoDB chiamata interfaccia HandlerSocket (precedentemente chiamata HANLDER) . Ciò consente di accedere ai dati che consente di ignorare tutti i protocolli SQL, ACID e MVCC . Sebbene sia possibile, IMHO MODO TROPPO COMPLICATO PER CODIFICARE E MANTENERE. AFAIK non c'è nulla in stampa che indichi se l'interfaccia HandlerSocket interagisce con gen_clust_index o meno.

In sintesi, ci sono molti modi per scuoiare un gatto. In questo caso, non è possibile ottenere una sospensione del gatto (gen_clust_index). Immagino che questo sia il motivo per cui MyISAM continua a esistere per le sue prestazioni di lettura, la sua flessibilità nell'ordinamento delle tabelle, il formato delle righe delle tabelle e gli strumenti a supporto. InnoDB rimarrà progettato attorno alla sua natura conforme ACID fino a quando un'anima coraggiosa prende il codice sorgente InnoDB e lo trasforma in qualcosa che ha il meglio di MyISAM e InnoDB .


3

L' indice cluster è forse il motivo delle prestazioni di concorrenza di InnoDB su spin drive tradizionali.

L'accesso a una riga tramite l'indice cluster è rapido perché i dati della riga si trovano sulla stessa pagina in cui conduce la ricerca dell'indice. Se una tabella è grande, l'architettura dell'indice cluster spesso salva un'operazione di I / O del disco rispetto alle organizzazioni di archiviazione che archiviano i dati di riga utilizzando una pagina diversa dal record dell'indice. (Ad esempio, MyISAM utilizza un file per le righe di dati e un altro per i record di indice.)

L'I / O del disco è costoso. Ridurre questo è un enorme vantaggio per migliorare la concorrenza.

Se l'I / O del disco inizia a diventare più economico e con un minore collo di bottiglia (ad esempio, quando la tecnologia SSD diventa più stabile), Oracle potrebbe decidere di modificare il funzionamento degli indici InnoDB. Più probabilmente rimarrà lo stesso, perché la stessa tecnologia renderà meno "problematica la limitazione della RAM".


3

Risposta breve: No.

Cluster InnoDB tramite la chiave primaria e, in assenza di una chiave primaria, seleziona il primo indice univoco. In assenza di un indice univoco, crea una chiave nascosta a 6 byte per il clustering.

Quando hai la chiave nascosta a 6 byte, tutti gli indici secondari fanno riferimento a questa chiave, anziché puntatori esatti alle posizioni delle righe (come in MyISAM), quindi finisci con un attraversamento della chiave secondaria e quindi un attraversamento della chiave primaria per trovare i tuoi record .


Per estrapolare un po 'dalla tua domanda, presumo che tu sia preoccupato per la memoria adatta ad un albero, perché per cercare in modo efficiente, tutti i nodi radice dovrebbero essere in memoria, dal momento che devi sempre percorrere questo percorso per trovare le tue pagine foglia?

Questo è vero, ma una consolazione è che i database commerciali cercano di rendere i loro alberi più grassi possibile, piuttosto che profondi. Prova a eseguire xtrabackup --stats sui tuoi dati per vedere. Per esempio:

<INDEX STATISTICS>
  table: test/table1, index: PRIMARY, space id: 12, root page 3
  estimated statistics in dictionary:
    key vals: 25265338, leaf pages 497839, size pages 498304
  real statistics:
     level 2 pages: pages=1, data=5395 bytes, data/pages=32%
     level 1 pages: pages=415, data=6471907 bytes, data/pages=95%
        leaf pages: recs=25958413, pages=497839, data=7492026403 bytes, data/pages=91%

C'erano 497839 pagine in foglia (~ 8 GB), ma solo 416 pagine in alto (6,5 MB). Ho eseguito questo comando alcune volte sui dati di produzione e mi sorprende sempre quando ho milioni di miliardi di record e solo livello 1-3 pagine + pagine foglia.

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.