MySQL: perché non indicizzare ogni campo?


107

Recentemente ho imparato la meraviglia degli indici e le prestazioni sono migliorate notevolmente. Tuttavia, con tutto quello che ho imparato, non riesco a trovare la risposta a questa domanda.

Gli indici sono fantastici, ma perché qualcuno non potrebbe semplicemente indicizzare tutti i campi per rendere la tabella incredibilmente veloce? Sono sicuro che ci sia una buona ragione per non farlo, ma che ne dici di tre campi in una tabella di trenta campi? 10 in un campo 30? Dove si dovrebbe tracciare la linea e perché?


7
prova a inserire un valore in una tabella con oltre 10.000 voci indicizzate, tutte le voci devono essere aggiornate a causa di inserimenti / eliminazioni e questo è un enorme sovraccarico di tempo e un po 'di memoria se ogni valore ha un indice
Jesus Ramos

5
C'è un motivo in più oltre allo spazio e alle prestazioni di scrittura: l'utilizzo di più indici per un singolo accesso alla tabella è molto inefficiente . Ciò significa che, anche se si dispone di un indice su ogni colonna, le prestazioni di selezione non sono molto buone se si accede a più colonne nella clausola WHERE. In tal caso, è preferibile un indice a più colonne.
Markus Winand

1
se hai una tabella con 30 campi dovresti davvero guardare le strutture della tua tabella. Dovrebbe essere molto difficile lavorare con loro.
web

Risposte:


122

Gli indici occupano spazio in memoria (RAM); Troppi o troppo grandi di indici e il DB dovrà scambiarli da e verso il disco. Aumentano inoltre i tempi di inserimento e cancellazione (ogni indice deve essere aggiornato per ogni dato inserito / cancellato / aggiornato).

Non hai memoria infinita. Fare in modo che tutti gli indici entrino nella RAM = buono.

Non hai tempo infinito. L'indicizzazione delle sole colonne che è necessario indicizzare riduce al minimo le prestazioni di inserimento / eliminazione / aggiornamento.


11
Bella risposta casuale per dare una comprensione generale, ma non molto di aiuto per determinare effettivamente dove tracciare la linea sugli indici. Come puoi saperlo? Basta aggiungerli ai campi comunemente WHERED e sperare per il meglio?
Andrew

@Andrew un anno e mezzo dopo, hai trovato la risposta alla tua domanda?
Sinjai

1
@Sinjai Aggiungerli alle colonne in cui si trovano comunemente è probabilmente una buona regola pratica. Ma per il resto potresti fare molte letture a quanto pare se vuoi diventare esperto di indici. per esempio. stackoverflow.com/questions/3049283/…
Andrew,

Non dimenticare lo spazio su disco.
jpmc26

27

Tieni presente che ogni indice deve essere aggiornato ogni volta che una riga viene aggiornata, inserita o eliminata. Quindi più indici hai, minori saranno le prestazioni per le operazioni di scrittura.

Inoltre, ogni indice occupa ulteriore spazio su disco e memoria (quando viene chiamato), quindi potrebbe potenzialmente rallentare anche le operazioni di lettura (per tabelle di grandi dimensioni). Controllalo


6
Il collegamento è per MS SQL Server ; questa domanda è per MySQL
OMG Ponies

5
@OMG la maggior parte dei punti nel collegamento si applica a tutti i principali RDBMS
RichardTheKiwi

5
@Richard aka cyberkiwi: gli indici non sono coperti da ANSI - è un miracolo che ogni fornitore abbia usato una terminologia simile. Ma anche in questo caso, solo SQL Server e MySQL utilizzano la terminologia "cluster" e "non cluster" - significa più in SQL Server che in MySQL. Non c'è nulla che garantisca che i consigli per un fornitore debbano essere applicati a un altro.
OMG Pony

3
@omg i primi 6 punti si applicano a qualsiasi dbms. salta quelli non / cluster, poi in basso ci sono altri punti riguardanti l'indicizzazione generale, anche sul punto. Se hai cose specifiche che vuoi sottolineare, chiamale. Altrimenti sembra che tu stia negando tutte le risposte che dai commenti (inclusa la tua risposta cancellata), che nessuno è d'accordo con la tua valutazione.
RichardTheKiwi

10

Devi bilanciare le esigenze di CRUD. La scrittura sulle tabelle diventa lenta. Per quanto riguarda il punto in cui tracciare la linea, dipende da come si accede ai dati (filtro di ordinamento, ecc.).


e inoltre ogni indice occupa un po 'di spazio nel database
Acanthus

@Acanthus: i dischi rigidi più piccoli disponibili sono misurati in gigabyte .
OMG Ponies

4
@OMG ma non RAM come sottolinea Brian. non è mai una buona idea immagazzinare più del necessario. memorizzazione nella cache di dati / indici nella RAM, supporti di backup (versioni che si adattano per nastro, ecc.) Sono tutti influenzati da indici inutili
RichardTheKiwi

9
L'abbondanza di una risorsa non è motivo di spreco o inefficienza.
Smandoli

6
Vero, ma i vincoli non sono quelli di 10+ anni fa.
OMG Ponies

2

L'indicizzazione occuperà più spazio allocato sia dall'unità che dalla ram, ma migliorerà anche notevolmente le prestazioni. Sfortunatamente quando raggiunge il limite di memoria, il sistema cede lo spazio su disco e ne rischia le prestazioni. In pratica, non dovresti indicizzare alcun campo che potresti pensare non coinvolga in alcun tipo di algoritmo di attraversamento dei dati, né inserimento né ricerca (clausola WHERE). Ma dovresti in caso contrario. Per impostazione predefinita, devi indicizzare tutti i campi. I campi che dovresti considerare non indicizzabili sono se le query sono utilizzate solo dal moderatore, a meno che non necessitino anche di velocità


2

questa risposta è la mia opinione personale basata su cui sto usando la mia logica matematica per rispondere

la seconda domanda riguardava il confine dove fermarsi, prima facciamo qualche calcolo matematico, supponiamo di avere N righe con L campi in una tabella se indicizziamo tutti i campi otterremo una L nuove tabelle indice dove ogni tabella ordinerà in a in modo significativo i dati del campo indice, a prima vista se la tua tabella è un peso W diventerà W * 2 (1 tera diventerà 2 tera) se hai 100 tavoli grandi (ho già lavorato nel progetto dove era il numero della tabella intorno al tavolo 1800) sprecherai 100 volte questo spazio (100 tera), questo è tutt'altro che saggio.

Se applicheremo gli indici in tutte le tabelle dovremo pensare agli aggiornamenti degli indici se un aggiornamento attiva tutti gli aggiornamenti degli indici questoèun equivalente selezionato nel tempo non ordinato

da ciò concludo che hai in questo scenario che se perdi questo tempo è preferibile perderlo in una selezione né in un aggiornamento perché se selezionerai un campo che non è indicizzato non innescherai un'altra selezione su tutti i campi che sono non indicizzato

cosa indicizzare?

chiavi esterne: è un must basato su

chiave primaria: non sono ancora sicuro che potrebbe essere se qualcuno leggesse questo potrebbe aiutare in questo caso

altri campi: la prima risposta naturale è la metà dei restanti fild perché: se devi indicizzare di più non sei lontano dalla risposta migliore se dovresti indicizzare di meno non sei anche lontano perché sappiamo che nessun indice è cattivo e tutto indicizzato è anche un male.

da questi 3 punti posso concludere che se abbiamo campi L composti da chiavi K il limite dovrebbe essere da qualche parte vicino ((L-K)/2)+Kpiù o meno a L / 10

questa risposta si basa sulla mia logica e sui miei prezzi personali


1

Non è una buona idea indicizzare tutte le colonne di una tabella. Sebbene ciò renderà la tabella molto veloce da leggere, diventerà anche molto più lenta da scrivere. Scrivere su una tabella in cui ogni colonna è indicizzata comporterebbe l'inserimento del nuovo record in quella tabella e quindi l'inserimento delle informazioni di ciascuna colonna nella propria tabella indice.


Non sono sicuro se renderebbe la lettura della tabella velocissima, soprattutto se la tabella dati è di soli 100 MB ma la index.table 300 MB o più.
David

Tutto quello che hai detto è stato detto prima.
Vael Victus
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.