2016-06-13 15 views
5

Ho chiesto più domande sugli indici. Qualcosa del genere:Cosa succede quando creo un indice su una colonna?

Le seguenti query trarranno beneficio da questo indice? mytable(col1, col2, col3)

. . . WHERE col1 = ? AND col3 = ? 
. . . WHERE col2 = ? 
. . . WHERE col1 IN (?, ?) 
. . . WHERE col3 = ? AND col1 NOT IN (?, ?) 
. . . WHERE col1 = ? OR col2 = ? 
. . . WHERE col2 = ? AND col1 = ? 
. . . WHERE col1 = ? AND col2 > ? 
. . . WHERE col1 = ? AND col3 > ? 

-- each question was containing one of these queries ;-) 

Ogni volta che ho avuto una risposta per quella query specifica che è stato menzionato in questa domanda, e ancora non riesco a giudicare un tale indice sarebbe utile per una query o meno. (o come renderlo più ottimale)

Così ho deciso di fare questa domanda e voglio sapere del backstage. Cosa succede quando creo un indice su una colonna? Un indice è fatto di cosa? Un indice di colonne multiple contiene le righe (perché l'ordine è importante)? Come funziona che causa una query molto più veloce?

In realtà ho bisogno di alcune informazioni sugli indici per rendermi in grado come posso determinare un indice corretto (colonne multiple o singola colonna) per una query.

Nota: Ho alcune esperienze per lavorare con EXPLAIN. E sì, lo so che usare EXPLAIN è davvero utile in questi casi. Ora ho solo bisogno di ulteriori informazioni.

risposta

1

Questo eval si basano esclusivamente sulla clausola in cui si mostra ... può cambiare a seconda della colonna selezionare

. . . WHERE col1 = ? AND col3 = ?    yes partial (only col1) 
    . . . WHERE col2 = ?       no 
    . . . WHERE col1 IN (?, ?)      yes 
    . . . WHERE col3 = ? AND col1 NOT IN (?, ?)  yes partial (only col1) 
    . . . WHERE col1 = ? OR col2 = ?    yes 
    . . . WHERE col2 = ? AND col1 = ?    yes 
    . . . WHERE col1 = ? AND col2 > ?    yes 
    . . . WHERE col1 = ? AND col3 > ?    yes partial (only col1) 

per una buona spiegazione di come il lavoro indice su mysql è possibile vedere questo riferimento http://dev.mysql.com/doc/refman/5.7/en/mysql-indexes.html

dal documento

MySQL utilizza indici per queste operazioni:

Per trovare rapidamente le righe corrispondenti a una clausola WHERE.

Per eliminare righe dalla considerazione. Se esiste una scelta tra gli indici multipli , MySQL normalmente utilizza l'indice che trova il numero più piccolo di righe (l'indice più selettivo). Se la tabella ha un indice a colonne multiple, è possibile utilizzare il prefisso più a sinistra dell'indice dall'ottimizzatore per cercare le righe. Ad esempio, se hai un indice di tre colonne su (col1, col2, col3), hai indicizzato le funzioni di ricerca su (col1), (col1, col2) e (col1, col2, col3). Per ulteriori informazioni su , vedere Sezione 9.3.5, "Indicatori a più colonne".

Per recuperare righe da altre tabelle durante l'esecuzione di join. MySQL può utilizzare gli indici su colonne in modo più efficiente se sono dichiarati come lo stesso tipo e dimensione. In questo contesto, VARCHAR e CHAR sono considerati uguali se dichiarati della stessa dimensione. Ad esempio, VARCHAR (10) e CHAR (10) hanno la stessa dimensione, ma VARCHAR (10) e CHAR (15) non lo sono.

Per il confronto tra colonne di stringhe non binarie, entrambe le colonne devono utilizzare lo stesso set di caratteri per . Ad esempio, confrontando una colonna utf8 con una colonna latin1 preclude l'uso di un indice.

Il confronto di colonne dissimili (confrontare una colonna di stringhe con una colonna temporale o numerica , ad esempio) può impedire l'uso di indici se i valori non possono essere confrontati direttamente senza conversione. Per un dato valore come 1 nella colonna numerica, potrebbe essere uguale a qualsiasi numero di valori nella colonna di stringhe come '1', '1', '00001' o '01 .e1 '. Questo esclude l'uso di qualsiasi indice per la colonna di stringhe.

Per trovare il valore MIN() o MAX() per una colonna indicizzata specifica key_col. Questo è ottimizzato da un preprocessore che controlla se si utilizza 01_WHERE key_part_N = costante su tutte le parti chiave che si verificano prima di key_col nell'indice. In questo caso, MySQL esegue una ricerca con chiave singola per ciascuna espressione MIN() o MAX() e la sostituisce con una costante . Se tutte le espressioni vengono sostituite con costanti, la query restituisce immediatamente. Ad esempio:

per ordinare o raggruppare una tabella se la selezione o raggruppamento avviene su un prefisso più a sinistra di un indice utilizzabile (ad esempio, ORDER BY key_part1, key_part2). Se tutte le parti chiave sono seguite da DESC, la chiave viene letta nell'ordine inverso . Vedi Sezione 9.2.1.15, "ORDINA PER OTTIMIZZAZIONE" e Sezione 9.2.1.16, "GRUPPO PER OTTIMIZZAZIONE".

In alcuni casi, una query può essere ottimizzata per recuperare i valori senza consultando le righe di dati. (Un indice che fornisce tutti i risultati necessari per una query è denominato indice di copertura.) Se una query utilizza da una tabella solo le colonne incluse in alcuni indici, i valori selezionati possono essere recuperati dall'albero indice per maggiori velocità:

+0

Grazie ... upvote –

+0

Grazie @Stack .. Ho aggiunto un po 'di parte del documento da MySQL .. spero utile – scaisEdge

1

Un indice inserisce il valore o parte del valore in RAM in modo che sia più veloce per l'accesso. Un indice con più di una colonna aggrega i contenuti.

Quindi un indice con (col1, col2, col3) sarà utile per tutte le query che contengono le ricerche col1, perché col1 è il più a sinistra.

sarà ancora più vantaggioso per le ricerche di col1 e col2, perché dopo aver ottenuto tutte le partite per col1, allora può usare la parte col2 troppo.

Infine, la parte col3 verrà sempre utilizzata solo se sono già stati utilizzati col1 e col2, quindi è improbabile che sia utile. Ma potrebbe essere.

+0

Grandi spiegazioni .. grazie .. upvote –

1

Bene, non c'è mai una risposta corretta sull'indicizzazione, la risposta corretta sarà diversa ogni volta a seconda della dimensione dei dati, dei tipi di colonne e di ETC.

al momento di decidere quali indici è meglio per un tavolo si dovrebbe considerare quanto segue:

  • Quali sono le funzioni più comuni che sto facendo su questo tavolo?
  • Quante volte al giorno questa funzione si verifica?
  • Quali sono le query più lente che influiscono maggiormente sulle mie prestazioni?

Dopodiché, quando hai le domande che devi effettivamente migliorare (un aggiornamento che accade molto, un select/join e ETC) puoi decidere quali sono gli indici corretti con il piano di spiegazione da ogni query.

Si deve sapere che quando l'indicizzazione come vostro esempio mytable(col1, col2, col3), sarà in grado di utilizzare anche solo una parte dell'indice fino a quando la colonna di necessità è menzionato prima nell'indice

Così, ogni uso di Col1 anzi sarà essere in grado di utilizzare questo indice. Col2 verrà utilizzato solo nel caso in cui sia combinato con Col1 e così via per Col3 (deve essere combinato con entrambi col1 e col2 per essere utilizzato).

È possibile trovare un sacco di informazioni sull'indicizzazione on MySQL documantation .

+1

vedo .. grazie .. upvote –

1

Sarebbe seguente query beneficiare di questo indice mytable (col1, col2, col3)

. . . WHERE col1 = ? AND col3 = ? 

col1 beneficia l'indice e per il predicato residuale col3 può essere utilizzato

. . . WHERE col2 = ? 

SQL può scegliere di eseguire la scansione l'indice si ha se è conveniente, quindi in sintesi questo voleva essere utilizzato

Indice
. . . WHERE col1 IN (?, ?) 

verrà utilizzato

. . . WHERE col3 = ? AND col1 NOT IN (?, ?) 

benefici col1 dall'indice e per col3 residua predicato verrà utilizzato

. . . WHERE col1 = ? OR col2 = ? 

Indice verrà utilizzato

.210

Indice verrà utilizzato

. . . WHERE col1 = ? AND col2 > ? 

Indice verrà utilizzato

. . . WHERE col1 = ? AND col3 > ? 

Indice verrà utilizzato

Un residuo predicato è una sonda che SQL si applica alle righe rimaste dopo l'applicazione prima indice.

+0

Ok .. grazie .. upvote –