SQL est un langage déclaratif, pas un langage procédural. En d'autres termes, vous construisez une instruction SQL pour décrire les résultats que vous souhaitez obtenir. Vous ne dites pas au moteur SQL comment pour faire le travail.
En règle générale, il est préférable de laisser le moteur et l'optimiseur SQL trouver le meilleur plan de requête. Le développement d'un moteur SQL représente de nombreuses années-personnes d'efforts, alors laissez les ingénieurs faire ce qu'ils savent faire.
Bien entendu, il existe des situations où le plan d'interrogation n'est pas optimal. Vous souhaitez alors utiliser des astuces de requête, restructurer la requête, mettre à jour les statistiques, utiliser des tables temporaires, ajouter des index, etc. pour obtenir de meilleures performances.
Pour ce qui est de votre question. Les performances des ETC et des sous-requêtes devraient, en théorie, être les mêmes puisque les deux fournissent les mêmes informations à l'optimiseur de requêtes. La différence réside dans le fait qu'un ETC utilisé plusieurs fois peut être facilement identifié et calculé une seule fois. Les résultats pourraient alors être stockés et lus plusieurs fois. Malheureusement, SQL Server ne semble pas tirer parti de cette méthode d'optimisation de base (que l'on pourrait appeler l'élimination des sous-requêtes).
Les tables temporaires sont une question différente, car vous fournissez davantage d'indications sur la manière dont la requête doit être exécutée. Une différence majeure est que l'optimiseur peut utiliser les statistiques de la table temporaire pour établir son plan d'interrogation. Cela peut se traduire par des gains de performance. En outre, si vous avez un CTE (sous-requête) compliqué qui est utilisé plus d'une fois, le fait de le stocker dans une table temporaire permet souvent d'améliorer les performances. La requête n'est exécutée qu'une seule fois.
La réponse à votre question est qu'il faut jouer un peu pour obtenir les performances que vous attendez, en particulier pour les requêtes complexes qui sont exécutées régulièrement. Dans un monde idéal, l'optimiseur de requêtes trouverait le chemin d'exécution parfait. Même si c'est souvent le cas, vous pouvez peut-être trouver un moyen d'améliorer les performances.