SQL - це декларативна мова, а не процедура. Тобто ви будуєте оператор SQL для опису результатів, які ви хочете. Ви не говорите двигуну SQL, як робити роботу.
Як правило, це гарна ідея дозволити SQL-механізму та оптимізатору SQL знайти найкращий план запитів. Багато людей-років намагаються вкластись у розробку двигуна SQL, тому нехай інженери роблять те, що вміють робити.
Звичайно, бувають ситуації, коли план запитів не є оптимальним. Потім потрібно використовувати підказки для запитів, реструктурувати запит, оновлювати статистику, використовувати тимчасові таблиці, додавати індекси тощо, щоб отримати кращу ефективність.
Щодо вашого питання. Продуктивність CTE та підзапитів теоретично повинна бути однаковою, оскільки обидва надають однакову інформацію оптимізатору запитів. Одна відмінність полягає в тому, що CTE, що використовується більше, ніж один раз, можна було легко визначити та обчислити один раз. Потім результати можна зберігати і читати кілька разів. На жаль, SQL Server, схоже, не користується цим базовим методом оптимізації (ви можете назвати це загальне усунення підзапиту).
Тимчасові таблиці - це інша справа, оскільки ви надаєте більше вказівок щодо того, як слід проводити запит. Одна з головних відмінностей полягає в тому, що оптимізатор може використовувати статистику з тимчасової таблиці для встановлення свого плану запитів. Це може призвести до підвищення продуктивності. Крім того, якщо у вас є складний CTE (підзапит), який використовується не один раз, його зберігання у тимчасовій таблиці часто сприятиме підвищенню продуктивності. Запит виконується лише один раз.
Відповідь на ваше запитання полягає в тому, що вам потрібно пограти, щоб отримати очікувану ефективність, особливо для складних запитів, які виконуються регулярно. В ідеальному світі оптимізатор запитів знайде ідеальний шлях виконання. Хоча це часто трапляється, можливо, ви зможете знайти спосіб покращити продуктивність.