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

Mysql Exists vs IN - sous-requête corrélée vs sous-requête ?

Ceci est une réponse indépendante du SGBDR, mais peut néanmoins aider. Selon ma compréhension, la sous-requête corrélée (c'est-à-dire dépendante) est peut-être le coupable le plus souvent faussement accusé de mauvaises performances.

Le problème (comme il est le plus souvent décrit) est qu'il traite la requête interne pour chaque ligne de la requête externe. Par conséquent, si la requête externe renvoie 1 000 lignes et que la requête interne en renvoie 10 000, votre requête doit parcourir 10 000 000 lignes (externe × interne) pour produire un résultat. Comparé aux 11 000 lignes (externes+internes) d'une requête non corrélée sur les mêmes ensembles de résultats, ce n'est pas bon.

Cependant, ce n'est que le pire des scénarios. Dans de nombreux cas, le SGBD pourra exploiter les index pour réduire considérablement le nombre de lignes. Même si seule la requête interne peut utiliser un index, les 10 000 lignes deviennent ~13 recherches, ce qui réduit le total à 13 000.

Le exists l'opérateur peut arrêter de traiter les lignes après la première, ce qui réduit encore le coût de la requête, en particulier lorsque la plupart des lignes externes correspondent à au moins une ligne interne.

Dans de rares cas, j'ai vu SQL Server 2008R2 optimiser des sous-requêtes corrélées à une jointure de fusion (qui ne traverse les deux ensembles qu'une seule fois - meilleur scénario possible) où un index approprié peut être trouvé dans les requêtes internes et externes.

Le véritable coupable des mauvaises performances n'est pas nécessairement les sous-requêtes corrélées , mais analyses imbriquées .