Vedi How MySQL Uses Indexes.
Convalidare anche se MySQL esegue ancora un full table scan dopo aver aggiunto altre 2000 righe alla tabella user_metrics
. Nelle tabelle piccole, l'accesso per indice è in realtà più costoso (I/O-saggio) di una scansione della tabella e l'ottimizzatore di MySQL potrebbe tenerne conto.
Contrariamente al mio precedente post, si scopre che MySQL è anche using a cost-based optimizer, che è una buona notizia - che è, a condizione che si esegue il ANALYZE
almeno una volta quando si crede che il volume dei dati nel database è rappresentante del futuro utilizzo quotidiano.
Quando si utilizzano gli ottimizzatori basati sui costi (Oracle, Postgres, ecc.), È necessario assicurarsi di eseguire periodicamente lo ANALYZE
sulle varie tabelle poiché le loro dimensioni aumentano di oltre il 10-15%. (Postgres lo farà automaticamente per te, di default, mentre altri RDBMS lasceranno questa responsabilità a un DBA, cioè tu.) Tramite l'analisi statistica, ANALYZE
aiuterà l'ottimizzatore a farsi un'idea migliore di quanto I/O (e altri associati risorse, come la CPU, necessarie ad esempio per l'ordinamento) saranno coinvolte nella scelta tra i vari piani di esecuzione dei candidati. La mancata esecuzione ANALYZE
può provocare molto povere, le decisioni di pianificazione a volte disastrose (ad es millisecondo-query di prendere, a volte, ore a causa di cattivi cicli annidati su JOIN
s.)
Se le prestazioni sono ancora insoddisfacente dopo l'esecuzione ANALYZE
, poi in genere sarai in grado di risolvere il problema utilizzando i suggerimenti, ad es FORCE INDEX
, mentre in altri casi potresti esserti imbattuto in un bug di MySQL (ad esempio questo older one, che avrebbe potuto essere morso dovresti utilizzare Rails 'nested_set
).
Ora, poiché ci si trova in un'applicazione Rails, sarà ingombrante (e sconfiggere lo scopo di ActiveRecord
) a rilasciare le vostre query personalizzate con note invece di continuare a utilizzare i ActiveRecord
quelli -Generata.
avevo detto che in applicazione nostri Rails tuttiSELECT
query è sceso al di sotto di 100 ms dopo il passaggio a Postgres, mentre alcuni del complesso join generati da ActiveRecord
ogni tanto prendere quanto 15s o più con MySQL 5.1 a causa dei cicli annidati con le scansioni del tavolo interno, anche quando gli indici erano disponibili. Nessun ottimizzatore è perfetto e devi essere consapevole delle opzioni. Altri potenziali problemi di prestazioni da tenere in considerazione, oltre all'ottimizzazione del piano di query, sono bloccanti. Questo è al di fuori della portata del tuo problema però.
Che cosa significa la tua N? Sono costanti letterali, colonne o variabili? È importante. – Quassnoi
Siamo spiacenti, quelli sono stati incollati dall'output del mio plugin query_reviewer. Le query effettive contengono numeri interi - es. IN (25, 26, 27) – jasonlong
@blackant: hai eseguito l'analisi sui tuoi tavoli? – vladr