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

MySQL non utilizza gli indici con la clausola WHERE IN?

Vedi Come MySQL utilizza gli indici .

Verifica anche se MySQL esegue ancora una scansione completa della tabella dopo aver aggiunto circa 2000 righe aggiuntive al tuo user_metrics tavolo. Nelle tabelle piccole, l'accesso per indice è in realtà più costoso (in termini di I/O) rispetto alla scansione di una tabella e l'ottimizzatore di MySQL potrebbe tenerne conto.

Contrariamente al mio post precedente , si scopre che MySQL utilizza un ottimizzatore basato sui costi , che è un'ottima notizia, a condizione che tu esegua il tuo ANALYZE almeno una volta quando ritieni che il volume di dati nel tuo database sia rappresentativo del futuro utilizzo quotidiano.

Quando si ha a che fare con ottimizzatori basati sui costi (Oracle, Postgres, ecc.), è necessario assicurarsi di eseguire periodicamente ANALYZE sui vari tavoli poiché la loro dimensione aumenta di oltre il 10-15%. (Postgres lo farà automaticamente per te, per impostazione predefinita, mentre altri RDBMS lasceranno questa responsabilità a un DBA, ovvero a te.) Attraverso l'analisi statistica, ANALYZE aiuterà l'ottimizzatore a farsi un'idea migliore di quanto I/O (e altre risorse associate, come la CPU, necessarie ad esempio per l'ordinamento) saranno coinvolti nella scelta tra i vari piani di esecuzione candidati. Impossibile eseguire ANALYZE può portare a decisioni di pianificazione molto scadenti, a volte disastrose (ad es. query di millisecondi che richiedono, a volte, ore a causa di loop nidificati errati su JOIN s.)

Se le prestazioni non sono ancora soddisfacenti dopo aver eseguito ANALYZE , in genere sarai in grado di aggirare il problema utilizzando suggerimenti, ad es. FORCE INDEX , mentre in altri casi potresti esserti imbattuto in un bug di MySQL (ad esempio questo uno più vecchio , che ti avrebbe morso se avessi usato il nested_set di Rails ).

Ora, dato che sei in un'app Rails , sarà ingombrante (e vanificherà lo scopo di ActiveRecord ) per inviare suggerimenti alle tue query personalizzate invece di continuare a utilizzare ActiveRecord -generati.

L'avevo menzionato nella nostra applicazione Rails all SELECT le query sono scese al di sotto di 100 ms dopo il passaggio a Postgres, mentre alcuni dei complessi join generati da ActiveRecord occasionalmente richiedeva fino a 15 secondi o più con MySQL 5.1 a causa di loop nidificati con scansioni di tabelle interne, anche quando erano disponibili indici. Nessun ottimizzatore è perfetto e dovresti essere a conoscenza delle opzioni. Altri potenziali problemi di prestazioni di cui essere a conoscenza, oltre all'ottimizzazione del piano di query, sono il blocco. Tuttavia, questo non rientra nell'ambito del tuo problema.