使用 SQL Server 2016。
我有一个存储过程,可以针对一系列日期生成选项列表。为了清楚起见,针对几天的运输选项,但对这里的细节并不重要。
存储过程的第一步会生成一个日期列表以存储其他数据,并且生成此列表所花费的时间比代码的余额要长得多。虽然这个过程很短,但调用次数意味着这段代码使系统承受的负载比其他任何东西都多。
考虑到这一点,我一直在测试几个选项的效率。
迭代公用表表达式:
CREATE FUNCTION [dbo].[udf_DateRange_CTE] (@StartDate DATE,@EndDate DATE)
RETURNS @Return TABLE (Date DATE NOT NULL)
AS
BEGIN
WITH dates(date)
AS (SELECT @StartDate [Date]
UNION ALL
SELECT DATEADD(dd, 1, [Date])
FROM dates
WHERE [Date] < @EndDate
)
INSERT INTO @Return
SELECT date
FROM dates
OPTION (MAXRECURSION 0)
RETURN
END
一个while循环:
CREATE FUNCTION [dbo].[udf_DateRange_While] (@StartDate DATE,@EndDate DATE)
RETURNS @Retun TABLE (Date DATE NOT NULL,PRIMARY KEY (Date))
AS
BEGIN
WHILE @StartDate <= @EndDate
BEGIN
INSERT INTO @Retun
VALUES (@StartDate)
SET @StartDate = DATEADD(DAY,1,@StartDate)
END
RETURN
END
从预先填充的日期表中查找:
CREATE FUNCTION [dbo].[udf_DateRange_query] (@StartDate DATE,@EndDate DATE)
RETURNS @Return TABLE (Date DATE NOT NULL)
AS
BEGIN
INSERT INTO @Return
SELECT Date
FROM DateLookup
WHERE Date >= @StartDate
AND Date <= @EndDate
RETURN
END
在效率方面,我进行了 1000 次测试,生成了一年的日期,结果如下:
- CTE:10.0 秒
- 时间:7.7 秒
- 查询:2.6 秒
从这一点来看,查询绝对是更快的选择,但确实需要一个需要创建和维护的永久日期表。这意味着查询不再是“独立的”,并且可以请求给定日期范围之外的日期。
有谁知道为某个范围生成日期的任何更有效的方法,或者我可以应用于上述任何优化?
非常感谢。