Maison > Article > base de données > Pourquoi une requête MySQL \"IN\" avec une sous-requête est-elle significativement plus lente qu'avec des valeurs explicites ?
Écart de performances entre les sous-requêtes et les requêtes à valeur explicite "IN"
Pourquoi une requête MySQL "IN" est-elle significativement plus lente lors de l'utilisation d'une sous-requête que lorsque vous utilisez des valeurs explicites ?
Considérez la requête suivante :
<code class="sql">SELECT COUNT(DISTINCT subscriberid) FROM em_link_data WHERE linkid IN (SELECT l.id FROM em_link l WHERE l.campaignid = '2900' AND l.link != 'open')</code>
Cette requête prend environ 18 secondes à s'exécuter, malgré le fait que la sous-requête à elle seule se termine en moins de 1 ms.
Cependant, lorsque la sous-requête est remplacée par des valeurs explicites :
<code class="sql">SELECT COUNT(DISTINCT subscriberid) FROM em_link_data WHERE linkid IN (24899,24900,24901,24902);</code>
La requête se termine en moins d'1 milliseconde.
Explication
L'écart de performances provient de la manière dont MySQL évalue les sous-requêtes. Les sous-requêtes sont exécutées à chaque fois qu'elles sont rencontrées, ce qui signifie que dans la première requête, MySQL exécute essentiellement sept millions de requêtes (évaluation de la sous-requête pour chaque ligne de la table "em_link_data"). En revanche, lors de l'utilisation de valeurs explicites, la sous-requête n'est évaluée qu'une seule fois.
Solution de contournement
Si la réécriture de la requête à l'aide d'un JOIN n'est pas une option, vous pouvez envisager d'utiliser un cache de requêtes pour améliorer les performances. Le cache de requêtes stocke les résultats des requêtes précédemment exécutées et les réutilise si la même requête est à nouveau exécutée. Cela peut réduire considérablement le temps d'exécution des requêtes gourmandes en sous-requêtes.
Pour activer le cache de requêtes, ajoutez la ligne suivante à votre fichier de configuration MySQL :
query_cache_type = 1
Redémarrez MySQL pour les modifications apportées prendre effet.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!