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

Indici fulltext e compositi e come influiscono sulla query

Se ho capito la tua domanda, sai che MATCH AGAINST usa il tuo indice FULLTEXT e ti stai chiedendo come fa MySQL ad applicare il resto della clausola WHERE (es. esegue una scansione delle tabelle o una ricerca indicizzata).

Ecco cosa presumo sulla tua tabella:ha una CHIAVE PRIMARIA su alcune colonne id e l'indice FULLTEXT.

Quindi, prima di tutto, MySQL mai utilizzare l'indice FULLTEXT per la clausola WHERE della città/stato. Come mai? Perché gli indici FULLTEXT si applicano solo con MATCH AGAINST. Vedi qui nel paragrafo dopo la prima serie di elenchi puntati (non i punti elenco del sommario).

MODIFICA: Nel tuo caso, supponendo che la tua tabella non abbia solo 10 righe, MySQL applicherà l'indice FULLTEXT per il tuo MATCH AGAINST, quindi eseguirà una scansione delle tabelle su quei risultati per applicare la città/stato DOVE.

E se aggiungessi un indice BTREE su città e stato?

CREATE INDEX city__state ON table (city(10),state(2)) USING BTREE;

Bene MySQL può usarne solo uno index per questa query poiché è una semplice selezione. Sarà uno usa il TESTO COMPLETO o il BTREE. Si noti che quando dico un indice, intendo una definizione di indice, non una colonna in un indice multiparte. Comunque, questo allora pone la domanda quale fa usa?

Dipende dall'analisi della tabella. MySQL tenterà di stimare (basato sulle statistiche della tabella dell'ultima OPTIMIZE TABLE) quale indice eliminerà la maggior parte dei record. Se la città/stato WHERE ti porta a 10 record mentre MATCH AGAINST ti porta solo a 100, MySQL utilizzerà l'indice city__state prima per la città/stato DOVE e quindi eseguire una scansione delle tabelle per la PARTITA CONTRO.

D'altra parte, se MATCH_AGAINST ti porta a 10 record mentre la città/stato WHERE ti porta solo a 1000, MySQL applicherà prima l'indice FULLTEXT e la scansione delle tabelle per città e stato.

La linea di fondo è la cardinalità del tuo indice In sostanza, quanto sono unici i valori che andranno nel tuo indice? Se ogni record nella tua tabella ha la città impostata su Oakland, allora non è una chiave molto univoca e quindi avere città ='Oakland' non riduce molto il numero di record per te. In tal caso, diciamo che il tuo indice city__state ha una bassa cardinalità .

Di conseguenza, se il 90% delle parole nel tuo indice FULLTEXT sono "John", anche questo non ti aiuta molto per gli stessi identici motivi.

Se puoi permetterti lo spazio e il sovraccarico UPDATE/DELETE/INSERT, consiglierei di aggiungere l'indice BTREE e lasciare che MySQL decida quale indice vuole usare. In base alla mia esperienza, di solito fa un ottimo lavoro nel scegliere quello giusto.

Spero che risponda alla tua domanda.

MODIFICA: In una nota a margine, assicurati di scegliere la dimensione giusta per il tuo indice BTREE (nel mio esempio ho scelto i primi 10 caratteri in città). Questo ovviamente ha un enorme impatto sulla cardinalità. Se hai scelto city(1), ovviamente otterrai una cardinalità inferiore rispetto a city(10).

EDIT2: Il piano di query (stima) di MySQL per il quale l'indice elimina la maggior parte dei record è quello che vedi in EXPLAIN.