Question

Question 1:

Lorsque nous exécutons une requête, le plan d'exécution change-t-il à chaque fois lors de l'exécution de la requête?

Si oui, avez-vous eu des problèmes de performances?

Si non, si nous modifions quelque chose dans la table, c'est-à-dire en ajoutant un index, comment la base de données sait-elle qu'il y a quelque chose qu'elle peut utiliser pour changer le plan d'exécution pour une exécution plus rapide?

Question 2:

Mais quel est l'ordre général d'exécution lors de l'exécution d'une requête de jointure, surtout s'il y a beaucoup de jointures (externe, interne, naturelle, si plusieurs externe).

Était-ce utile?

La solution

  • Pour être exact pour SQL Server :

Vous avez au maximum deux plans en cache (un parallèle et un non parallèle). Ensuite, le plan est utilisé avec un contexte d'exécution par utilisateur. Plus d'informations dans ma réponse ici

  • La commande JOIN n'est pas pertinente dans presque tous les cas

SQL est déclaratif. Cela signifie que vous indiquez au moteur ce que vous voulez et que l’optimiseur élabore le meilleur plan (dans des cas raisonnables, il peut prendre 2 semaines pour élaborer le meilleur). C’est pourquoi vous pouvez réécrire les requêtes de différentes façons pour obtenir la même réponse.

Comme pour toute règle concernant le SGBDR, il existe des exceptions. Pour les requêtes complexes, l’optimiseur ne passe pas par toutes les permutations, l’ordre JOIN peut donc compter: cela dépend du moment où l’optimiseur en décide suffisamment…

Autres conseils

(En supposant que SQL Server soit ici, vous n'avez pas spécifié ...)

Les plans d'exécution sont mis en cache et peuvent être réutilisés dans la mesure où vous paramétrez vos requêtes.

Lorsque vous modifiez la table ou les index sous-jacents, SQL Server connaît la date de modification de ces éléments par rapport au plan d'exécution mis en cache et peut réévaluer la requête pour les nouvelles conditions. Même chose lorsque les statistiques sont mises à jour ... parfois, les données réelles déterminent le plan, pas seulement la conception de table / index.

Les jointures ne sont pas effectuées dans un ordre basé sur inner vs outer, mais plutôt sur ce que l'optimiseur pense entraînera l'exécution de la requête le plus rapidement possible. Les détails varieront selon les bases de données. Mais en gros, l’optimiseur de requêtes essaie d’optimiser l’utilisation des index.

Supposons que vous ayez eu cette requête:

select a.foo, b.bar
from a
join b on b.b_id=a.b_id
where a.some_number=42;

Supposons maintenant que vous avez un index unique sur b.b_id mais aucun index sur a.some_number.

L’optimiseur de requêtes dispose alors de deux choix: il peut effectuer une lecture séquentielle de fichier complet sur b, puis pour chaque b effectuer une lecture séquentielle de fichier complet lors de la recherche d’une correspondance sur b_id et nom_un = 42. Cela se lit a ^ b enregistrements. Ou bien, il pourrait effectuer une lecture séquentielle du fichier complet lors de la recherche de some_number = 42, puis utiliser un index pour chaque index afin de rechercher rapidement l’enregistrement de b avec b_id correspondant. C'est-à-dire, lisez un * 2 enregistrements. Évidemment, le deuxième plan est bien meilleur, et c’est ce qu’il choisira.

Plus vous ajoutez de tables, plus le calcul devient compliqué, mais le principe est le même. Les jointures qui entraînent une lecture rapide de l'index à l'aide des valeurs trouvées dans d'autres tables seront effectuées plus tard, après la lecture des autres tables. Les tables qui doivent être lues de manière séquentielle, quels que soient l’événement ou les endroits où la lecture est basée sur des constantes plutôt que sur des valeurs d’autres enregistrements, sont généralement lues d’abord.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top