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

MySQL EXPLAIN 'type' cambia da 'range' a 'ref' quando viene modificata la data nell'istruzione where?

Strategie di ricerca diverse hanno senso per dati diversi. In particolare, le scansioni dell'indice (come l'intervallo) spesso devono eseguire una ricerca per leggere effettivamente la riga. Ad un certo punto, fare tutte quelle ricerche è più lento che non usare affatto l'indice.

Prendi un esempio banale, una tabella con tre colonne:id (chiave primaria), nome (indicizzato), compleanno. Supponiamo che abbia molti dati. Se chiedi a MySQL di cercare il compleanno di Bob, può farlo abbastanza rapidamente:in primo luogo, trova Bob nell'indice dei nomi (questo richiede alcune ricerche, log(n) dove n è il conteggio delle righe), quindi un'ulteriore ricerca per leggi la riga effettiva nel file di dati e leggi il compleanno da essa. È molto veloce e molto più veloce della scansione dell'intera tabella.

Quindi, considera di creare un name like 'Z%' . Questa è probabilmente una porzione abbastanza piccola del tavolo. Quindi è ancora più veloce trovare dove iniziano le Z nell'indice dei nomi, quindi per ognuno cerca il file di dati per leggere la riga. (Questa è una scansione dell'intervallo).

Infine, considera di chiedere tutti i nomi che iniziano con M-Z. Probabilmente è circa la metà dei dati. Potrebbe eseguire una scansione dell'intervallo e quindi un lotto di ricerche, ma cercare in modo casuale sul file di dati con l'obiettivo finale di leggere metà delle righe non è ottimale:sarebbe più veloce eseguire solo una grande lettura sequenziale del file di dati. Quindi, in questo caso, l'indice verrà ignorato.

Questo è ciò che stai vedendo, tranne nel tuo caso, c'è un'altra chiave su cui può fare affidamento. (È anche possibile che possa effettivamente utilizzare l'indice della data se non avesse l'altro, dovrebbe scegliere l'indice più veloce. Fai attenzione perché l'ottimizzatore di MySQL commette spesso errori in questo.)

Quindi, in breve, questo è previsto. Una query non dice come per recuperare i dati, invece dice cosa dati da recuperare. L'ottimizzatore del database dovrebbe trovare il modo più rapido per recuperarlo.

Potresti trovare un indice su entrambi colonne, nell'ordine (public_key,created_on_date) è preferito in entrambi i casi e velocizza la tua query. Questo perché MySQL può utilizzare sempre e solo un indice per tabella (per query). Inoltre, la data va alla fine perché una scansione dell'intervallo può essere eseguita in modo efficiente solo sull'ultima colonna di un indice.

[InnoDB in realtà ha un altro livello di indirizzamento, credo, ma confonderebbe solo il punto. Non fa differenza per la spiegazione.]