"CREATE INDEX` in MySQL è un'operazione lineare?


20

Quello che voglio dire è il seguente:

Se la creazione di un indice su una tabella con nrighe richiede ttempo. La creazione di un indice sulla stessa tabella 1000*nrichiede circa 1000*ttempo.

Quello che sto cercando di ottenere è stimare il tempo necessario per creare l'indice sul database di produzione creando lo stesso indice su un database di test molto più piccolo.

Risposte:


16

La creazione di un indice è essenzialmente un'operazione di ordinamento , quindi nella migliore delle ipotesi presenta una complessità di crescita dell'ordine n log n(in alcuni casi potresti trovarlo meglio e probabilmente non farà molto peggio).

Se tutte le tue pagine di dati rilevanti si adattano alla RAM e sono già nella RAM, e anche l'indice si adatta, e il tuo DBMS non forza la scrittura delle pagine di indice prima che la creazione sia completa (quindi i blocchi di indice non vengono aggiornati sul disco più volte durante l'operazione), quindi la velocità di scrittura dell'indice risultante su disco sarà più significativa del tempo impiegato per eseguire l'ordinamento, quindi potresti scoprire di avvicinarti a una relazione lineare tra il numero di righe e il tempo impiegato dalla creazione dell'indice - ma se supponi il caso peggiore, avrai meno probabilità di essere spiacevolmente sorpreso!

Ricordare che, a meno che non si interromperà l'accesso al database di produzione durante l'operazione, qualsiasi indice creato sarà in competizione per la larghezza di banda IO e / o i blocchi con altre attività, quindi si dovrebbe provare a tenerne conto se si stanno eseguendo i test di stima del tempo su un altro sistema anche se è configurato in modo identico.


7

Vale anche la pena notare che se puoi dividere i mandrini per gli indici dai mandrini per la tabella, sarai in grado di lavorare da due dischi contemporaneamente (sarà comunque limitato alla velocità del controller del disco nel mezzo, se un RAID o simili, ma sarà comunque più veloce di un disco).

Mi rendo conto che la creazione di un indice non è completamente un'operazione di lettura e scrittura simulata, ma accelera notevolmente le cose.

CAVEATS: Sono un ragazzo MSSQL, quindi non sono sicuro di MySQL, ma devo immaginare che il concetto di divisione dei mandrini non sia specifico per SQL Server e Oracle (di cui ho sentito parlare anche lì, IIRC ). Semplicemente non saprei come impostare questo concetto. Ma in termini di SQL Server ciò significherebbe avere un filegroup separato oltre PRIMARYe mettere gli indici sull'altro filegroup, con l'altro filegroup assegnato a un set di mandrini che non coinvolge PRIMARY(il posizionamento del mandrino garantito rispetto ai filegroup è un'altra storia del tutto)


1
Praticamente la stessa cosa in Oracle - solo i gruppi di file sono chiamati tablespace
Joe


1

Dipende.

Variabile n. 1: se MySQL sceglie di creare gli indici al volo o attendi che tutti i dati siano presenti, fai un ordinamento, ecc. Per creare l'indice. Nota: gli indici UNIQUE (penso) devono essere costruiti al volo in modo che UNIQUEness possa essere verificato. Il PRIMARY KEY per InnoDB è memorizzato con i dati (o è possibile dichiararlo viceversa), in modo che DEVE essere creato in modo casuale.

Variabile n. 2: L'indice tiene traccia dei dati (ad es. AUTO_INCREMENT o timestamp) rispetto a quelli casuali (GUID, MD5) o in un punto intermedio (numero parte, nome, friend_id).

Variabile n. 3 (se l'indice è creato al volo): l'indice potrebbe rientrare nella cache (key_buffer o innodb_buffer_pool) o potrebbe fuoriuscire sul disco.

Gli indici che tracciano i dati sono efficienti e praticamente lineari, indipendentemente dalla risposta al n. 1.

Gli ID casuali sono un dolore. Se l'indice non si adatta alla cache, il tempo per crearlo sarà molto peggio di quello lineare, indipendentemente dalle altre variabili. (Non sono d'accordo con Rolando in questo caso.) Un'enorme tabella InnoDB con un GUID per il PK è dolorosamente lenta da INSERIRE nel piano su 100 righe / sec per i dischi ordinari; forse 1000 se hai SSD. CARICARE DATI e INSERTI in batch non ti farà superare la lentezza della memorizzazione casuale.

Da 3.53 a 5.6 - non è cambiato molto.

Mandrini multipli? Lo striping RAID è migliore in quasi tutte le situazioni rispetto all'assegnazione manuale a questo e a quello lì. La suddivisione manuale porta a situazioni sbilanciate: una scansione della tabella è bloccata sul disco dati; un'operazione di solo indice è bloccata sul disco di indice; una query solitaria colpisce prima il disco indice, quindi il disco dati (nessuna sovrapposizione); eccetera.

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.