我将这个简单的SQL作为SSIS任务中的源:
Select * from budgetview
来源是:
CREATE VIEW [dbo].[BudgetView] AS
SELECT DISTINCT Country,
SDCO AS Company,
SDAN8 AS Customer,
SDLITM AS PrintableItemNumber,
dbo.fn_DateFromJulian(SDIVD) AS Date,
SDPQOR/100.0 AS Quantity,
SDAEXP/100.0 AS Value,
SDITWT/10000.0 AS Weight
FROM dbo.F553460
索引没有建议,每件事情似乎都已优化。
函数fn_DateFromJulian
源是:
CREATE FUNCTION [dbo].[fn_DateFromJulian]
(
@JulianDate numeric(6,0)
)
RETURNS date
AS
BEGIN
declare @resultdate date=dateadd(year,@JulianDate/1000,'1900-01-01')
set @resultdate=dateadd(day,@JulianDate%1000 -1,@resultdate)
return @resultdate
END
问题在于我正在等待大约20分钟,才能让SSIS中的行进入....
我在开始前等待20分钟
有没有找到罪魁祸首的建议?
答案 0 :(得分:3)
我的假设是通过计算Julian日期值来消耗花在视图上的时间。如果没有看到实际的查询计划,基于以下文章,这似乎是一个公平的猜测。
将原始函数重写为下面的表值函数(我只是简单地将您的代码混合在一起,可能有改进的机会)
CREATE FUNCTION dbo.fn_DateFromJulianTVF
(
@JulianDate numeric(6,0)
)
RETURNS TABLE AS
RETURN
(
SELECT dateadd(day,@JulianDate%1000 -1,dateadd(year,@JulianDate/1000,CAST('1900-01-01' AS date))) AS JDEDate
)
用法是
CREATE VIEW [dbo].[BudgetView] AS
SELECT DISTINCT Country,
SDCO AS Company,
SDAN8 AS Customer,
SDLITM AS PrintableItemNumber,
J.JDEDate AS [Date],
SDPQOR/100.0 AS Quantity,
SDAEXP/100.0 AS Value,
SDITWT/10000.0 AS Weight
FROM dbo.F553460 AS T
CROSS APPLY
dbo.fn_DateFromJulianTVF(T.SDIVD) AS J
标量值函数,类似于代码重用的气味,像重复使用的一次性尿布一样执行
答案 1 :(得分:1)
只是检查,但我是否理解为T.SDIVD
的每个唯一值只有一个唯一的函数结果值?换句话说,没有两个不同的T.SDIVD
将从函数返回相同的值?
在这种情况下,这里发生的事情(恕我直言)是你首先扫描整个表,因为每个记录计算f(SDIVD)值,然后通过聚合(DISTINCT)发送整个结果集。 / p>
由于函数在MSSQL中远非最佳,我建议通过转换事件链来限制它们的使用,并按照以下方式执行:
CREATE VIEW [dbo].[BudgetView] AS
SELECT /* DISTINCT */
Country,
Company,
Customer,
PrintableItemNumber,
dbo.fn_DateFromJulian(SDIVD) AS Date,
Quantity,
Value,
Weight
FROM (
SELECT DISTINCT Country,
SDCO AS Company,
SDAN8 AS Customer,
SDLITM AS PrintableItemNumber,
SDIVD,
SDPQOR/100.0 AS Quantity,
SDAEXP/100.0 AS Value,
SDITWT/10000.0 AS Weight
FROM dbo.F553460 ) dist_F553460
)
如果你有很多双重记录,这应该可以提高性能,如果你只有很少的记录,那么它就不会产生太大的影响,如果有的话。如果你知道你没有双打,你应该首先摆脱DISTINCT
,因为这是导致延迟的原因!
无论如何,关于这个功能你可以添加以下技巧:
CREATE FUNCTION [dbo].[fn_DateFromJulian]
(
@JulianDate numeric(6,0)
)
RETURNS date
WITH SCHEMABINDING
AS
BEGIN
declare @resultdate date=dateadd(year,@JulianDate/1000,'1900-01-01')
set @resultdate=dateadd(day,@JulianDate%1000 -1,@resultdate)
return @resultdate
END
WITH SCHEMABINDING
会导致一些内部优化,使其执行速度稍快一些,YMMV。它有局限性,但在这里它可以很好地工作。
编辑:删除'外部'DISTINCT,因为它(可能是我的第一个假设)不需要。