Che cosa significa "indice" su RDBMS? [chiuso]


21

Uso gli indici come fanno la maggior parte degli sviluppatori (principalmente su ... beh! Indice), ma sono sicuro che esiste un modo molto sottile di ottimizzare un database usando index. Non sono sicuro che sia specifico per qualsiasi implementazione di un DBMS.

La mia domanda è: quali sono buoni esempi di come utilizzare l'indice (tranne casi ovvi di base) e in che modo un DBMS ottimizza il suo database quando si specifica un indice su una tabella?


Nel pensare ulteriormente a questa domanda, questa domanda è troppo generica per questo sito. Se cambiamo l'ambito della domanda che potrebbe essere appropriata, altrimenti questa domanda non è appropriata per il sito.
jcolebrand

Mi piace spiegare gli indici usando la libreria metafora mysqlperformanceblog.com/2011/08/30/… Vedi se questo aiuta ..
Jonathan

Risposte:


11

Pensa a un indice come a "indice" ... che è un elenco ordinato di puntatori a posizioni in un file, noto anche come offset. Supponi di avere milioni di record memorizzati in una tabella, piuttosto che cercare nella tabella i criteri di corrispondenza, è molto più veloce fare riferimento a un elenco ordinato per le corrispondenze, quindi impilare i puntatori sulle righe di corrispondenza specifiche. Un esempio perfetto di un indice è un campo chiave primaria delle tabelle, in genere il suo campo "id". Se si desidera l'ID riga # 11234566, è molto più veloce chiedere all'indice un puntatore ai dati piuttosto che scansionare l'origine dati per la posizione 11234566.

Ecco un uso non così ovvio dell'indicizzazione:

CREATE TABLE activity_log (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
activity_type_id SMALLINT UNSIGNED NOT NULL,
datetime_created DATETIME
KEY(activity_type_id),
PRIMARY KEY(id)
);
CREATE TABLE activity_log_to_date_key (
activity_log_id INT UNSIGNED NOT NULL,
date_created_key  INT UNSIGNED NOT NULL REFERENCES dim_datetime(id),
UNIQUE KEY(activity_log_id),
KEY(date_created_key)
);
CREATE TABLE dim_datetime (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
date_hour DATETIME NOT NULL,
PRIMARY KEY(id),
KEY(date_hour)
);

L'operazione può creare il record del registro, ma quindi creare un riferimento a un datetime indicizzato che è più veloce da cercare / ordinare rispetto alla tabella del registro. Quindi unire nuovamente la tabella dei registri sulla propria chiave primaria. Se hai bisogno di me per approfondire questo, fammi sapere. Spero che abbia senso.

Query di esempio:

SELECT a.activity_log_id, al.activity_type_id, al.datetime_created
FROM activity_log_to_date_key a 
INNER JOIN dim_datetime d ON (d.id = a.date_created_key)
LEFT JOIN activity_log al ON (al.id = a.activity_log_id)
WHERE d.date_hour BETWEEN '2009-01-01 00:00:00' AND '2009-06-01 12:00:00';

grazie, è molto chiaro! Nel tuo esempio, "PRIMARY" cambierà il modo in cui RDMBS memorizza lo "scostamento" o viene utilizzato solo per vincoli di unicità?
Thomas Joulin,

9

Un punto che molte persone sembrano perdere è che un DBMS utilizzerà spesso (o può solo) solo un indice per riferimento di tabella in una query, e se può e usa più indici sarebbe probabilmente più veloce usare una combinazione indice se presente.

Ad esempio, se si cercano righe di una tabella di grandi dimensioni, WHERE AnIntegerColumn = 42 AND AnOtherInt = 69il percorso più rapido verso tali righe sarebbe un indice sulle due colonne AnIntegerColumn e AnOtherInt. Se si dispone solo di un indice su ciascuno di essi, ma nessun indice combinato, il DB cercherà l'uno o l'altro indice e filtrerà separatamente i risultati con la seconda clausola, oppure scansionerà entrambi e sposerà i risultati in seguito.

Un'altra semplice operazione comune che può essere migliorata con gli indici compositi è WHERE SomeColumn = <SomeValue> ORDER BY SomeOtherColumn: se esiste un indice su SomeColumn e SomeOtherColumn (nell'ordine giusto), le operazioni di filtro e ordinamento possono essere eseguite contemporaneamente in alcune circostanze.

L'aggiunta di troppi indici può ovviamente essere una cattiva ottimizzazione, poiché lo spazio aggiuntivo utilizzato per memorizzare gli indici (e il carico di I / O per mantenerli se il DB vede molte operazioni di scrittura) potrebbe essere un problema peggiore rispetto alle query di lettura leggermente meno ottimali , quindi non esagerare.


2

David e Randy hanno questo coperto. Volevo solo aggiungere che il EXPLAINcomando può essere di grande aiuto per capire quando otterrai un grande risparmio dalla creazione di un indice, oltre a suggerire quali indici sono necessari. Verranno visualizzati i passaggi che il database sta eseguendo per eseguire la query, in modo da sapere quali bit impiegano più tempo.


Per aggiungere alla risposta di Gaurav, usa "SPIEGA ESTESO", quindi digita immediatamente "MOSTRA AVVERTENZE" per vedere come viene tradotta la tua query.
randomx,

1

Qualcosa che non ho ancora visto menzionato qui è che quando hai più di un disco probabilmente vuoi mettere il tuo indice su un disco diverso rispetto a dove si trovano effettivamente i dati. Questo può velocizzare alcune operazioni. Penso che questo meriti una domanda nel suo diritto.


Questo era vero ma in questi giorni diciamo di non provare a indovinare il tuo sottosistema I / O. Non sai comunque dove un array di archiviazione posizionerà i tuoi dati.
Gaius,

1
@gaius Intendevo piuttosto se non avessi una configurazione RAID5 (o simili), per mettere gli indici su E :, i dati su F :, ecc.
jcolebrand
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.