Это проблема оптимизации. Если вы посмотрите на планы выполнения, вы поймете, почему один из них намного быстрее, чем другие.
Во-первых, вторые два одинаковы. Представление подзапросов в виде CTE или подзапросов не меняет план выполнения в SQL Server.
Почему версия временной таблицы быстрее? Простой ответ заключается в том, что он получает лучший план выполнения.
Но возникает вопрос. Причина в том, что алгоритм, используемый для объединения двух таблиц. В версиях CTE / подзапросов SQL Server должен угадать, сколько строк сгенерировано. Основываясь на этом числе, он выбирает лучший алгоритм.
В версии временной таблицы данные уже находятся в таблице, поэтому SQL Server не нужно угадывать.
Итак, временные таблицы могут создавать лучшие планы выполнения. Позвольте мне сделать несколько оговорок. Использование временных таблиц сопряжено с большими затратами - на самом деле данные должны где-то храниться. Это также ограничивает возможности для оптимизации (что в данном случае хорошо, но в других случаях этого не может быть).
Вы должны иметь возможность добавить подсказку для ускорения других версий. Я бы предположил что-то вроде OPTION (HASH JOIN)
.
Вы также можете настроить индексы для оптимизации всех трех версий.