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

Ottimizzazione delle query MySQL - query interne

Puoi sempre utilizzare EXPLAIN o EXPLAIN EXTENDED per vedere cosa sta facendo MySql con una query

Potresti anche scrivere la tua query in un modo leggermente diverso, hai provato quanto segue?

SELECT        s.*, 
              sm.url AS media_url 
FROM          shows AS s
INNER JOIN    show_medias AS sm ON s.id = SM.show_id
WHERE `s`.`id` IN ( 
                        SELECT DISTINCT st.show_id 
                        FROM show_time_schedules AS sts 
                        LEFT JOIN show_times AS st ON st.id = sts.show_time_id 
                        WHERE sts.schedule_date BETWEEN CAST('2012-01-10' AS date) AND CAST('2012-01-14' AS date) 
                        ) 
AND            `s`.`is_active` = 1 
AND            sm.is_primary = 1
ORDER BY       s.name asc 

Sarebbe interessante vedere quale sia l'effetto di ciò. Mi aspetto che sia più veloce poiché, al momento, penso che MySql eseguirà la query interna 1 per ogni spettacolo che hai (in modo che una query venga eseguita più volte. Un join dovrebbe essere più efficiente.)

Sostituisci INNER JOIN con un LEFT JOIN se vuoi tutti gli spettacoli che non hanno una riga in show_medias.

MODIFICA:

Darò un'occhiata al tuo EXPLAIN EXTENDED a breve, mi chiedo anche se vuoi provare quanto segue; rimuove tutte le sottoquery:

SELECT        DISTINCT s.*,  
                       sm.url AS media_url  
FROM                   shows AS s 
INNER JOIN             show_medias AS sm ON s.id = SM.show_id
INNER JOIN             show_times AS st ON (s.id = st.show_id)
RIGHT JOIN             show_time_schedules AS sts ON (st.id = sts.show_time_id)

WHERE                  `s`.`is_active` = 1  
AND                    sm.is_primary = 1 
AND                    sts.schedule_date BETWEEN CAST('2012-01-10' AS date) AND CAST('2012-01-14' AS date)  
ORDER BY               s.name asc 

(Sarebbe anche bello vedere SPIEGAZIONE ESTESA su questi - potresti aggiungerlo ai commenti per questo).

Ulteriore MODIFICA:

Sul tuo EXPLAIN EXTENDED (un buon inizio su come leggere questi è qui )

USING FILESORT e USING TEMPORARY sono entrambi indicatori chiave. Si spera che la seconda query che raccomando dovrebbe rimuovere tutte le tabelle TEMPORANEE (nella sottoquery). Prova quindi a lasciare l'ORDER BY disattivato per vedere se questo fa la differenza (e possiamo aggiungerlo ai risultati ottenuti finora :-)

Posso anche vedere che la query sta potenzialmente perdendo molte ricerche nell'indice; tutte le tue colonne id sono i principali candidati per le corrispondenze dell'indice (con il solito avvertimenti sugli indici ). Proverei anche ad aggiungere quegli indici e quindi a eseguire nuovamente EXPLAIN EXTENDED per vedere qual è la differenza ora (EDIT come già sappiamo dal tuo commento sopra!)