Mysql
 sql >> Database >  >> RDS >> Mysql

Indicizzazione corretta quando si utilizza l'operatore OR

Hai frainteso come funzionano gli indici.

Pensa a un elenco telefonico (l'equivalente di un indice a due colonne su cognome, nome e cognome). Se ti chiedo di trovare tutte le persone nell'elenco telefonico il cui cognome è "Smith", puoi trarre vantaggio dal fatto che i nomi sono ordinati in questo modo; puoi presumere che gli Smith siano organizzati insieme. Ma se ti chiedo di trovare tutte le persone il cui nome è "John" non ottieni alcun beneficio dall'indice. I John possono avere qualsiasi cognome, quindi sono sparsi per tutto il libro e finisci per dover cercare nel modo più duro, da una copertina all'altra.

Ora, se ti chiedo di trovare tutte le persone il cui cognome è "Smith" OPPURE il cui nome è "John", puoi trovare gli Smith facilmente come prima, ma questo non ti aiuta affatto a trovare i John. Sono ancora sparsi nel libro e devi cercarli nel modo più difficile.

È lo stesso con gli indici a più colonne in SQL. L'indice è ordinato per la prima colonna, quindi ordinato per la seconda colonna in caso di parità nella prima colonna, quindi ordinato per la terza colonna in caso di parità in entrambe le prime due colonne, ecc. Non è ordinato per tutte le colonne contemporaneamente. Quindi il tuo indice a più colonne non aiuta a rendere più efficienti i tuoi termini di ricerca, ad eccezione della colonna più a sinistra nell'indice.

Torna alla tua domanda originale.

Crea un indice separato a colonna singola su ciascuna colonna. Uno di questi indici sarà una scelta migliore rispetto agli altri, in base a stima di quante operazioni di I/O l'indice verrà addebitato se viene utilizzato.

Le versioni moderne di MySQL hanno anche una certa intelligenza sulla fusione degli indici , quindi la query può utilizzare più di un indice in una determinata tabella, quindi provare a unire i risultati. Altrimenti MySQL tende ad essere limitato a utilizzare un indice per tabella in una determinata query.

Un altro trucco che molte persone usano con successo è eseguire una query separata per ciascuna delle colonne indicizzate (che dovrebbe utilizzare il rispettivo indice) e quindi UNION i risultati.

SELECT fields FROM table WHERE field1='something' 
UNION
SELECT fields FROM table WHERE field2='something' 
UNION
SELECT fields FROM table WHERE field3='something' 
UNION
SELECT fields FROM table WHERE field4='something' 

Un'ultima osservazione:se ti ritrovi a cercare lo stesso 'something' in quattro campi, dovresti riconsiderare se tutti e quattro i campi sono effettivamente la stessa cosa e sei colpevole di aver progettato una tabella che viola il primo modulo normale con gruppi ripetuti . In tal caso, forse da campo1 a campo4 appartengono a una singola colonna in una tabella figlio. Quindi diventa molto più semplice indicizzare e interrogare:

SELECT fields from table INNER JOIN child_table ON table.pk = child_table.fk
WHERE child_table.field = 'something'