TSQL查看选择优化功能时存在(TSQL view select optimization when

2019-10-21 14:49发布

我有这个简单的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分钟出现之前得到启动

是否有任何建议,找到罪魁祸首?

Answer 1:

我的假设是,花费在视图中的时间是通过计算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/


Answer 2:

只是检查,但我在正确的理解,对于每一个独特的价值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,因为它是(有可能的,比照我的第一个假设)没有必要的。



文章来源: TSQL view select optimization when function is present