Mysql
 sql >> Base de données >  >> RDS >> Mysql

Optimisation des requêtes MySQL - requêtes internes

Vous pouvez toujours utiliser EXPLAIN ou EXPLAIN EXTENDED pour voir ce que fait MySql avec une requête

Vous pouvez également écrire votre requête d'une manière légèrement différente, avez-vous essayé ce qui suit ?

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 

Il serait intéressant de voir quel en est l'effet. Je m'attendrais à ce qu'il soit plus rapide car, pour le moment, je pense que MySql exécutera la requête interne 1 pour chaque émission que vous avez (de sorte qu'une requête sera exécutée plusieurs fois. Une jointure devrait être plus efficace.)

Remplacez INNER JOIN par LEFT JOIN si vous voulez que toutes les émissions n'aient pas de ligne dans show_medias.

MODIFIER :

Je vais jeter un œil à votre EXPLAIN EXTENDED sous peu, je me demande également si vous voulez essayer ce qui suit ; il supprime toutes les sous-requêtes :

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 

(Il serait également bon de voir EXPLAIN EXTENDED sur ceux-ci - vous pouvez l'ajouter aux commentaires pour celui-ci).

MODIFIER davantage :

Sur votre EXPLAIN EXTENDED (un bon début pour lire ces est ici )

USING FILESORT et USING TEMPORARY sont deux indicateurs clés. J'espère que la deuxième requête que je recommande devrait supprimer toutes les tables TEMPORARY (dans la sous-requête). Essayez ensuite de laisser ORDER BY désactivé pour voir si cela fait une différence (et nous pouvons ajouter cela aux résultats jusqu'à présent :-)

Je peux également voir que la requête manque potentiellement de nombreuses recherches d'index ; toutes vos colonnes id sont des candidats de choix pour les correspondances d'index (avec l'habituel avertissements d'index ). J'essaierais également d'ajouter ces index, puis d'exécuter à nouveau EXPLAIN EXTENDED pour voir quelle est la différence maintenant (EDIT comme nous le savons déjà grâce à votre commentaire ci-dessus !)