J'ai le même calcul dans les clauses SELECT et GROUP BY. Le serveur SQL effectue-t-il réellement ces calculs deux fois ou est-il suffisamment intelligent pour ne le faire qu'une seule fois?
La réponse simple est que SQL Server ne donne aucune garantie générale quant au moment et au nombre de fois où une expression scalaire sera évaluée au moment de l'exécution.
Il existe toutes sortes de comportements compliqués (et non documentés) dans l'optimiseur et le moteur d'exécution concernant le placement, l'exécution et la mise en cache des expressions scalaires. Books Online n'a pas grand-chose à dire à ce sujet, mais ce qu'il dit est le suivant:
Cela décrit l'un des comportements auxquels j'ai fait allusion auparavant, l'exécution différée des expressions. J'ai écrit sur certains des autres comportements actuels (qui pourraient changer à tout moment) dans ce billet de blog .
Une autre considération est que le modèle de coût utilisé par l'optimiseur de requêtes ne fait actuellement pas grand-chose en termes d'estimation des coûts pour les expressions scalaires. Sans un cadre de calcul des coûts robuste, les résultats actuels sont basés sur une large heuristique ou le pur hasard.
Pour les expressions très simples, cela ne fait probablement pas beaucoup de différence que l'expression soit évaluée une ou plusieurs fois dans la plupart des cas. Cela dit, j'ai rencontré de grandes requêtes où les performances ont été affectées négativement lorsque l'expression est évaluée de manière redondante un très grand nombre de fois, ou l'évaluation se produit sur un seul thread où il aurait été avantageux d'évaluer dans une branche parallèle de l'exécution plan.
En résumé, le comportement actuel n'est pas défini, et il n'y a pas grand-chose dans les plans d'exécution pour vous aider à comprendre ce qui s'est passé (et il ne sera pas toujours pratique d'attacher un débogueur pour examiner les comportements détaillés du moteur, comme dans le billet de blog).
Si vous rencontrez des cas où les problèmes d'évaluation scalaire sont importants pour les performances, soulevez le problème auprès du support technique Microsoft. Il s'agit de la meilleure façon de fournir des commentaires afin d'améliorer les futures versions du produit.
cross apply
dans ce cas est un peu exagérée, et elle nuirait très probablement aux performances en introduisant une auto-jointure inutile.CROSS APPLY
définit simplement l'alias des colonnes de la même ligne. Pas besoin de rejoindre. par exempleSELECT COUNT(*), hilo FROM master..spt_values CROSS APPLY (VALUES(high + low)) V(hilo) GROUP BY hilo
La performance n'est qu'un aspect. L'autre est la maintenabilité.
Personnellement, j'ai tendance à faire ce qui suit:
METTRE À JOUR:
Si vous n'aimez pas faire de l'imbrication, vous pouvez créer VIEW pour chaque table où vous devez utiliser des expressions complexes.
Ensuite, vous pouvez faire une sélection sans faire d'imbrication supplémentaire;
la source