Secondo il capitolo 9 (Parser e Optimizer), Pagina 172 del libro Comprensione di MySQL Internals di Sasha Pachev
ecco la suddivisione della valutazione di una query come le seguenti attività:
- Determinare quali chiavi possono essere utilizzate per recuperare i record dalle tabelle e scegliere quella migliore per ciascuna tabella.
- Per ogni tabella, decidere se la scansione di una tabella è migliore della lettura su un tasto. Se ci sono molti record che corrispondono al valore della chiave, i vantaggi della chiave vengono ridotti e la scansione della tabella diventa più veloce.
- Determinare l'ordine in cui le tabelle devono essere unite quando nella query è presente più di una tabella.
- Riscrivi le clausole WHERE per eliminare il codice morto, riducendo i calcoli non necessari e modificando i vincoli, ove possibile, per aprire la strada all'uso delle chiavi.
- Elimina le tabelle non utilizzate dal join.
- Determinare se i tasti possono essere utilizzati per
ORDER BY
e GROUP BY
.
- Tentare di semplificare le sottoquery e determinare fino a che punto è possibile memorizzare nella cache i loro risultati.
- Unisci viste (espandi il riferimento della vista come macro)
Sulla stessa pagina, dice quanto segue:
Nella terminologia dell'ottimizzatore MySQL, ogni query è un insieme di join. Il termine join viene utilizzato qui in modo più ampio rispetto ai comandi SQL. Una query su una sola tabella è un join degenerato. Mentre normalmente non pensiamo di leggere i record da una tabella come un join, le stesse strutture e gli algoritmi utilizzati con i join convenzionali funzionano perfettamente per risolvere la query con una sola tabella.
EPILOGO
A causa delle chiavi presenti, della quantità di dati e dell'espressione della query, MySQL Joins può talvolta fare cose per il nostro bene (o per tornare da noi) e trovare risultati che non ci aspettavamo e che non possiamo spiegare rapidamente.
Ho scritto su questa stranezza prima
perché lo Strumento per ottimizzare le query di MySQL potrebbe eliminare alcune chiavi durante la valutazione della query.
Il commento di @ Phil mi aiuta a vedere come pubblicare questa risposta (+1 per il commento di @ Phil)
Il commento di @ ypercube (+1 anche per questo) è una versione compatta del mio post perché l'ottimizzatore di query di MySQL è primitivo. Sfortunatamente, deve essere perché si occupa di motori di archiviazione esterni.
CONCLUSIONE
Per quanto riguarda la tua vera domanda, MySQL Query Optimizer determinerebbe le metriche delle prestazioni di ogni query al termine
- contando le righe
- selezione dei tasti
- massaggiare serie di risultati intermittenti
- Oh sì, sto facendo il vero JOIN
Probabilmente dovresti forzare l'ordine di esecuzione riscrivendo (refactoring) la query
Ecco la prima query che hai dato
select count(*)
from table1 a
join table2 b
on b.key_col=a.key_col
where b.tag = 'Y';
Prova a riscriverlo per valutare prima WHERE
select count(*)
from table1 a
join (select key_col from table2 where tag='Y') b
on b.key_col=a.key_col;
Ciò altererebbe sicuramente il piano EXPLAIN. Potrebbe produrre risultati migliori o peggiori.
Una volta ho risposto a una domanda in StackOverflow in cui ho applicato questa tecnica. EXPLAIN è stato orrendo, ma le prestazioni sono state dinamite. Funzionava solo perché erano presenti gli indici corretti e l'uso di LIMIT in una sottoquery .
Come per i prezzi delle azioni, quando si tratta di query e si tenta di esprimerle, si applicano restrizioni, i risultati possono variare e le performance passate non sono indicative di risultati futuri.