Как считает Митч Уит, в своем комментарии, вероятно, лучший способ улучшить производительность этого запроса - использовать таблицу чисел вместо рекурсивного CTE, используемого для генерации списка дат.
Если вы не можете или не хотите использовать таблицу чисел, производительность диапазона дат CTE может быть улучшена для больших диапазонов с помощью метода, предложенного Ициком Бен-Ганом:
DECLARE @t TABLE(startdate DATETIME , enddate DATETIME)
INSERT INTO @t
SELECT '8/01/2009','08/31/2009' UNION ALL
SELECT '2/01/1900','02/28/1900' UNION ALL
SELECT '10/01/1959','10/31/1959'
DECLARE @n INT
SET @n = DATEDIFF(dd,'19000201','20090831') + 1
;WITH base
AS
(
SELECT 1 AS n
UNION ALL
SELECT n+1 FROM base
WHERE n < CEILING(SQRT(@n))
)
,cross_cte
AS
(
SELECT 0 AS c
FROM base AS b1
,base AS b2
)
,dates_cte
AS
(
SELECT TOP(@n) CAST('19000201' AS DATETIME) - 1 + ROW_NUMBER() OVER(ORDER BY c) AS date
FROM cross_cte
)
SELECT DISTINCT d.DATE
FROM Dates_Cte d
JOIN @t t
ON d.DATE BETWEEN t.startdate AND t.enddate
OPTION ( MAXRECURSION 0);
В то время как план выполнения показывает, что эта версия немного менее эффективна, чем оригинальная (= ~ 1%), при измерении с SET STATISTICS TIME
в моей системе время, затраченное как на ЦП, так и на время ЦП, для этой версии будет меньше половины времени ваш.