Maison >base de données >tutoriel mysql >Pourquoi `IN` est-il plus lent que `=` dans les requêtes MySQL, même avec une seule valeur ?
IN
de MySQL par rapport à =
Le problème : Les requêtes MySQL utilisant l'opérateur IN
peuvent être étonnamment plus lentes que celles utilisant l'opérateur =
, même lorsque IN
se compare à une seule valeur.
Cause première : Le problème réside dans la façon dont MySQL gère les sous-requêtes dans les clauses IN
. Les anciennes versions (antérieures à 5.6) identifient souvent à tort ces sous-requêtes comme des sous-requêtes dépendantes.
Sous-requêtes dépendantes ou indépendantes : Une sous-requête dépendante est réexécutée pour chaque ligne de la requête externe, ce qui entraîne une surcharge de performances importante. Une sous-requête indépendante n'est exécutée qu'une seule fois. Les versions antérieures de MySQL traitaient à tort les IN
sous-requêtes comme dépendantes, même lorsqu'elles renvoyaient une seule valeur.
EXPLAIN Analysis : La commande EXPLAIN
révèle ce comportement. Une requête IN
avec une sous-requête affiche « SOUS-REQUÊTE DÉPENDANTE » dans le plan d'exécution, tandis qu'une requête équivalente utilisant =
affiche « SOUS-REQUÊTE ».
Exemple EXPLAIN
de sortie (montrant le problème) :
<code>1 'PRIMARY' 'question_law_version' 'ALL' '' '' '' '' 10148 'Using where' 2 'DEPENDENT SUBQUERY' 'question_law_version' 'ALL' '' '' '' '' 10148 'Using where' 3 'DEPENDENT SUBQUERY' 'question_law' 'ALL' '' '' '' '' 10040 'Using where'</code>
Exemple EXPLAIN
de résultat (après avoir résolu le problème avec =
) :
<code>1 'PRIMARY' 'question_law_version' 'ALL' '' '' '' '' 10148 'Using where' 2 'SUBQUERY' 'question_law_version' 'ALL' '' '' '' '' 10148 'Using where' 3 'SUBQUERY' 'question_law' 'ALL' '' '' '' '' 10040 'Using where'</code>
Exemple illustratif :
Cette simple requête illustre le problème :
<code class="language-sql">SELECT id FROM foo WHERE id IN (SELECT MAX(foo_id) FROM bar);</code>
Même avec une seule valeur renvoyée par la sous-requête, elle est traitée comme dépendante, ce qui entraîne une exécution lente. Remplacer IN
par =
améliore considérablement les performances.
Solution :
Le problème de performances a été résolu dans MySQL 5.6 et les versions ultérieures. La mise à niveau vers une version plus récente résout cet écart. Si la mise à niveau n'est pas réalisable, réécrire la requête pour éviter IN
avec une sous-requête (en utilisant des jointures, par exemple) peut être une solution de contournement.
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!