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

Éviter les requêtes imbriquées

Cela dépend vraiment, j'ai eu des situations où j'ai amélioré certaines requêtes en utilisant des sous-requêtes.

Les facteurs que je connais sont :

  • si la sous-requête utilise les champs de la requête externe pour la comparaison ou non (corrélé ou pas)
  • si la relation entre la requête externe et la sous-requête est couverte par des index
  • s'il n'y a pas d'index utilisables sur les jointures et que la sous-requête n'est pas corrélée et renvoie un petit résultat, il peut être plus rapide de l'utiliser
  • J'ai également rencontré des situations où transformer une requête qui utilise order by en une requête qui ne l'utilise pas et la transformer en une simple sous-requête et un tri qui améliore les performances dans mysql

Quoi qu'il en soit, il est toujours bon de tester différentes variantes (avec SQL_NO_CACHE s'il vous plaît), et transformer les requêtes corrélées en jointures est une bonne pratique.

J'irais même jusqu'à dire que c'est une pratique très utile.

Il est possible que si les requêtes corrélées sont les premières qui vous viennent à l'esprit que vous ne pensez pas principalement en termes d'opérations d'ensemble, mais principalement en termes d'opérations procédurales et lorsqu'il s'agit de bases de données relationnelles, il est très utile d'adopter pleinement l'ensemble perspective sur le modèle de données et ses transformations.

EDIT :Procédural vs Relationnel
Penser en termes d'opérations ensemblistes vs procédurales se résume à l'équivalence dans certaines expressions d'algèbre ensembliste, par exemple la sélection sur une union équivaut à l'union de sélections. Il n'y a pas de différence entre les deux.
Mais lorsque vous comparez les deux procédures, telles que l'application des critères de sélection à chaque élément d'une union, puis la création d'une union, puis l'application de la sélection, les deux procédures sont nettement différentes, ce qui pourrait ont des propriétés très différentes (par exemple, utilisation du processeur, des E/S, de la mémoire).

L'idée derrière les bases de données relationnelles est que vous n'essayez pas de décrire comment obtenir le résultat (procédure), mais seulement ce que vous voulez, et que le système de gestion de base de données décidera du meilleur chemin (procédure) pour répondre à votre demande. C'est pourquoi SQL est appelé langage de 4ème génération (4GL) .

L'une des astuces qui vous aide à le faire est de vous rappeler que les tuples n'ont pas d'ordre inhérent (les éléments d'ensemble ne sont pas ordonnés). Une autre consiste à réaliser que l'algèbre relationnelle est assez complète et permet la traduction des requêtes (exigences) directement en SQL (si la sémantique de votre modèle représente bien l'espace du problème, ou en d'autres termes si la signification attachée au nom de vos tables et relations est bien faite, ou en d'autres termes si votre base de données est bien conçue).

Par conséquent, vous n'avez pas à penser comment, seulement quoi.

Dans votre cas, c'était juste une préférence par rapport aux requêtes corrélées, il se peut donc que je ne vous dise rien de nouveau, mais vous avez souligné ce point, d'où le commentaire.

Je pense que si vous étiez complètement à l'aise avec toutes les règles qui transforment les requêtes d'un formulaire à un autre (règles telles que la distributivité) que vous ne préféreriez pas les sous-requêtes corrélées (que vous verriez toutes les formes comme égales).

(Remarque :ci-dessus traite du contexte théorique, important pour la conception de la base de données ; pratiquement les concepts ci-dessus divergent - toutes les réécritures équivalentes d'une requête ne sont pas nécessairement exécutées aussi rapidement, les clés primaires en cluster font que les tables héritent de l'ordre sur le disque, etc... mais ces les écarts ne sont que des écarts ; le fait que toutes les requêtes équivalentes ne s'exécutent pas aussi rapidement est une imperfection du SGBD réel et non des concepts qui le sous-tendent)