我有这个简单的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
有索引的NO意见,一切事情都似乎进行了优化。
功能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分钟出现之前得到启动
是否有任何建议,找到罪魁祸首?
我的假设是,花费在视图中的时间是通过计算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
标值函数,闻起来像代码重用,性能堪比重用一次性尿布
- https://sql.kiwi/2012/09/compute-scalars-expressions-and-execution-plan-performance.html
- http://blogs.lobsterpot.com.au/2011/11/08/when-is-a-sql-function-not-a-function/
只是检查,但我在正确的理解,对于每一个独特的价值T.SDIVD
会有的功能只是一个独特的结果值? 换句话说,没有两个不同的T.SDIVD
将返回从功能相同的值?
在这种情况下,这里发生了什么(恕我直言)是你第一次做扫描整个表,对每个记录计算F(SDIVD)值,然后通过聚合(DISTINCT)发送整个结果。
由于功能远远没有达到最佳的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
导致一些内部的优化,这将使其执行速度稍快,情况因人而异。 有它的局限性,但在这里它会很好地工作。
编辑:删除了“外” DISTINCT,因为它是(有可能的,比照我的第一个假设)没有必要的。