【发布时间】:2018-04-03 08:34:35
【问题描述】:
使用 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 秒
从这里查询绝对是更快的选择,但确实需要一个需要创建和维护的永久日期表。这意味着查询不再是“独立的”,并且可以请求给定日期范围之外的日期。
有谁知道为某个范围生成日期的任何更有效的方法,或者我可以对上述内容进行任何优化吗?
非常感谢。
【问题讨论】:
-
它是自包含的,如果它是所有日期但那是很多日期
标签: sql sql-server performance query-tuning