Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
当函数存在时,TSQL视图选择优化_Tsql_Ssis_Query Optimization - Fatal编程技术网

当函数存在时,TSQL视图选择优化

当函数存在时,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

我在SSIS任务中将以下简单SQL作为源:

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