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

Cacher/réutiliser une sous-requête dans MySQL

Voir ce que EXPLAIN EXTENDED dit.

S'il indique DEPENDENT SUBQUERY ou UNCACHEABLE SUBQUERY , il sera réévalué à chaque utilisation.

Cela se produit si la sous-requête utilise des variables de session ou est une sous-requête corrélée.

Si ce n'est pas le cas, il sera probablement mis en cache.

Si votre cas la sous-requête ne sera pas mise en cache, elle sera réévaluée dans chaque UNION 'ed set.

Votre sous-requête, cependant, semble être trop compliquée. Pourquoi n'utilisez-vous pas simplement :

SELECT id
FROM   playlist_program_map ppm, programs p
WHERE  ppm.playlist_id = 181
       AND p.id = ppm.program_id
       AND submitter_id = 32
       AND feed_id = 2478

Si vous avez un index sur playlist_program_map (playlist_id) , cette requête devrait fonctionner comme un charme.

Pourriez-vous me dire deux autres choses :

  1. Combien de lignes y a-t-il dans playlist_program_map et combien de DISTINCT playlist_id les valeurs sont-elles ?
    • Combien de lignes y a-t-il dans les programs et combien de DISTINCT submitter_id, feed_id y a-t-il des paires ?

D'après votre commentaire, je peux conclure qu'il y en a 10 programs par playlist en moyenne, et 200 programs par (submitter, feed) paire. Cela signifie que votre index sur playlist_program_map est plus sélectif que celui sur (submitter, feed) , et playlist_program_map doit être en tête dans la jointure.

L'index de texte intégral dans votre cas ne semble pas non plus très sélectif, étant donné que vous devez rejoindre 10 programmes sur 2 000 000 .

Vous feriez mieux d'essayer ce qui suit :

SELECT object_id, programs.created AS created
FROM   playlist_program_map ppm, programs p, comments_programs cp
WHERE  ppm.playlist_id = 181
       AND p.id = ppm.program_id
       AND p.submitter_id = 32
       AND p.feed_id = 2478
       AND cp.object_id = p.id
       AND cp.text REGEXP 'excellent'

, et répétez cette opération pour les trois tables.