当函数存在时,TSQL视图选择优化
我在SSIS任务中将以下简单SQL作为源:当函数存在时,TSQL视图选择优化,tsql,ssis,query-optimization,Tsql,Ssis,Query Optimization,我在SSIS任务中将以下简单SQL作为源: Select * from budgetview 资料来源是: CREATE VIEW [dbo].[BudgetView] AS SELECT DISTINCT Country, SDCO AS Company, SDAN8 AS Customer, SDLITM AS PrintableItemNumber, dbo.fn_DateFro
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
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
没有关于索引的建议,每件事似乎都是优化的
函数fn\u datefrom Julian
源代码为:
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
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分钟,只是为了让行进入SSI。。。。
我在那里等了20分钟才开始
有没有找到罪魁祸首的建议?我的假设是,在视图上花费的时间是通过计算朱利安日期值来消耗的。在没有看到实际的查询计划的情况下,根据下面的文章,这似乎是一个公平的猜测 将原始函数重写为下面的表值函数(我只是简单地将代码混合在一起,可能还有改进的机会) 用法将是
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
标量值函数,闻起来像代码重用,执行起来像可重用的一次性尿布
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
标量值函数,闻起来像代码重用,执行起来像可重用的一次性尿布
T.SDIVD
的每个唯一值,函数只有一个唯一的结果值?换句话说,没有两个不同的T.SDIVD
会从函数返回相同的值
在这种情况下,这里发生的事情(IMHO)是首先扫描整个表,为每个记录计算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
带有SCHEMABINDING的会导致一些内部优化,从而使其执行速度稍快,YMMV。它有局限性,但在这里它会很好地工作
编辑:删除了“outer”DISTINCT,因为它(可能是我的第一个假设)是不需要的。只是检查一下,但我是否正确理解,对于T.SDIVD
的每个唯一值,函数只有一个唯一的结果值?换句话说,没有两个不同的T.SDIVD
会从函数返回相同的值
在这种情况下,这里发生的事情(IMHO)是首先扫描整个表,为每个记录计算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
带有SCHEMABINDING的会导致一些内部优化,从而使其执行速度稍快,YMMV。它有局限性,但在这里它会很好地工作
编辑:删除“outer”DISTINCT,因为它(可能是我的第一个假设)是不需要的。在我看来,标量是一个邪恶的理想,它将成为一个内联表值函数,然后使用它。可能会为您节省一些处理时间。你可以做的另一件事是在提示下加速前10公里,但这里似乎有问题。你能帮我理解你的功能吗?看一下,我应该能够将2451545传递到函数中,并返回2001-01-1,但函数只接受6个数字。它是这样的:110235是2010年的第235天。我在我们的ERP中使用这个,JDEdwards。请看:没有函数的同一查询的性能如何?因此,如果我的答案没有真正解决问题,那么不要将其标记为这样。让我们看看发生了什么事。独角兽积分非常好,但让我们来解决问题。在ManagementDI中,点击Ctrl-M生成一个实际的查询计划,然后对视图运行SELECT语句。右键单击计划,另存为e4rthdog.sqlplan,然后发布到。。。sqlperformance.com或github,这样比我聪明的人就可以看到查询中发生了什么。另外,这个包中还有其他的数据流吗?或者您刚才展示的这个数据流?在我看来,标量是一个邪恶的理想,它将成为一个内联表值函数,然后使用它。可能会为您节省一些处理时间。你可以做的另一件事是在提示下加速前10公里,但这里似乎有问题。你能帮我理解你的功能吗?看一下,我应该能够将2451545传递到函数中,并返回2001-01-1,但函数只接受6个数字。它是这样的:110235是2010年的第235天。我在我们的ERP中使用这个,JDEdwards。请看:没有函数的同一查询的性能如何?因此,如果我的答案没有真正解决问题,那么不要将其标记为这样。让我们看看发生了什么事。独角兽积分非常好,但让我们来解决问题。在DI中,点击Ctrl-M生成实际的q