问题SQL:

  1. SELECT TOP 1001 ha.HuntApplicationID ,
    ha.PartyNumber ,
    mht.Name AS MasterHuntTypeName ,
    htly.LicenseYear ,
    lStatus.[Status] AS DrawTicketStatus ,
    isnull(dbo.udf_GetHuntApplicationPartyCount(ha.HuntApplicationID), 0) AS MemberCount ,
    count( won.DrawTicketLicenseID) AS DrawnMemberCount ,
    won.drawticketid ,
    dt.PreDrawNonResidentMemberCount AS NRMemberCount ,
    dbo.udf_GetAvgPreferencePoints(dt.DrawTicketID) AS PreferencePointAverage ,
    CASE
    WHEN ha.Quantity > 1 THEN NULL
    ELSE dt.PreDrawRandomNumber
    END AS PreDrawRandomNumber ,
    dsm.Name AS DrawSelectionMethodName ,
    dt.DrawnSequence ,
    dt.PreferencePointRank ,
    dt.DrawID ,
    dt.RandomRank
    FROM dbo.HuntApplication ha
    JOIN dbo.HuntTypeLicenseYear htly ON ha.HuntTypeLicenseYearID = htly.HuntTypeLicenseYearID
    JOIN dbo.MasterHuntType mht ON htly.MasterHuntTypeID = mht.MasterHuntTypeID
    LEFT JOIN dbo.HuntApplicationLicense hal ON ha.HuntApplicationID = hal.HuntApplicationID
    LEFT JOIN dbo.DrawTicket dt ON ha.HuntApplicationID = dt.HuntApplicationID
    LEFT JOIN dbo.DrawTicketLicense won ON dt.DrawTicketID = won.DrawTicketID
    AND won.WasDrawn = 1
    LEFT JOIN dbo.DrawSelectionMethod dsm ON dt.DrawSelectionMethodID = dsm.DrawSelectionMethodID
    LEFT JOIN dbo.StatusCode lStatus ON dt.StatusCodeID = lStatus.StatusCodeID
    JOIN dbo.DrawTicketHuntChoice dthc ON dt.DrawTicketID = dthc.DrawTicketID
    CROSS APPLY dbo.tvf_GetHuntApplicationPartyCount(ha.HuntApplicationID) hapc
    CROSS APPLY dbo.tvf_GetAvgPreferencePoints(dt.DrawTicketID) app
    WHERE 1 = 1
    AND htly.MasterHuntTypeID = @iMasterHuntTypeID
    AND htly.LicenseYear = @iLicenseYear
    AND dt.StatusCodeID = @iDrawTicketStatusCodeID
    AND dthc.WasDrawn = @iHuntChoiceWasDrawn
    GROUP BY ha.HuntApplicationID,
    ha.PartyNumber,
    mht.[Name],
    htly.LicenseYear,
    lStatus.[Status],
    isnull(dbo.udf_GetHuntApplicationPartyCount(ha.HuntApplicationID), 0),
    won.DrawTicketID,
    dt.PreDrawNonResidentMemberCount,
    dbo.udf_GetAvgPreferencePoints(dt.DrawTicketID),
    CASE
    WHEN ha.Quantity > 1 THEN NULL
    ELSE dt.PreDrawRandomNumber
    END,
    dsm.[Name],
    dt.DrawnSequence,
    dt.PreferencePointRank,
    dt.DrawID,
    dt.RandomRank
    ORDER BY htly.LicenseYear DESC,
    mht.Name,
    lStatus.[Status],
    dt.DrawID,
    PreferencePointAverage DESC,
    PreDrawRandomNumber,
    ha.PartyNumber

静态函数:

  1. CREATE FUNCTION [dbo].[udf_GetAvgPreferencePoints]
    (@DrawTicketID INT)
    RETURNS NUMERIC (18, 3)
    AS
    BEGIN
    RETURN
    (
    SELECT TOP 1
    CONVERT(DECIMAL, dt.PreDrawPreferencePointTotal) / NULLIF(CONVERT(DECIMAL, dt.PreDrawMemberCount),0)
    FROM dbo.DrawTicket dt
    WHERE dt.DrawTicketID = @DrawTicketID
    )
    END

执行时间40s

这是典型可以进行静态函数改写内联表值函数的sql:

改写后:

  1. SELECT TOP 1001 ha.HuntApplicationID ,
    ha.PartyNumber ,
    mht.Name AS MasterHuntTypeName ,
    htly.LicenseYear ,
    lStatus.[Status] AS DrawTicketStatus ,
    --isnull(dbo.udf_GetHuntApplicationPartyCount(ha.HuntApplicationID), 0) AS MemberCount ,
    isnull(hapc.MemberCount, 0) AS MemberCount,
    count( won.DrawTicketLicenseID) AS DrawnMemberCount ,
    won.drawticketid ,
    dt.PreDrawNonResidentMemberCount AS NRMemberCount ,
    --dbo.udf_GetAvgPreferencePoints(dt.DrawTicketID) AS PreferencePointAverage ,
    app.PreferencePointAverage PreferencePointAverage,
    CASE
    WHEN ha.Quantity > 1 THEN NULL
    ELSE dt.PreDrawRandomNumber
    END AS PreDrawRandomNumber ,
    dsm.Name AS DrawSelectionMethodName ,
    dt.DrawnSequence ,
    dt.PreferencePointRank ,
    dt.DrawID ,
    dt.RandomRank
    FROM dbo.HuntApplication ha
    JOIN dbo.HuntTypeLicenseYear htly ON ha.HuntTypeLicenseYearID = htly.HuntTypeLicenseYearID
    JOIN dbo.MasterHuntType mht ON htly.MasterHuntTypeID = mht.MasterHuntTypeID
    LEFT JOIN dbo.HuntApplicationLicense hal ON ha.HuntApplicationID = hal.HuntApplicationID
    LEFT JOIN dbo.DrawTicket dt ON ha.HuntApplicationID = dt.HuntApplicationID
    LEFT JOIN dbo.DrawTicketLicense won ON dt.DrawTicketID = won.DrawTicketID
    AND won.WasDrawn = 1
    LEFT JOIN dbo.DrawSelectionMethod dsm ON dt.DrawSelectionMethodID = dsm.DrawSelectionMethodID
    LEFT JOIN dbo.StatusCode lStatus ON dt.StatusCodeID = lStatus.StatusCodeID
    JOIN dbo.DrawTicketHuntChoice dthc ON dt.DrawTicketID = dthc.DrawTicketID
    CROSS APPLY dbo.tvf_GetHuntApplicationPartyCount(ha.HuntApplicationID) hapc
    CROSS APPLY dbo.tvf_GetAvgPreferencePoints(dt.DrawTicketID) app
    WHERE 1 = 1
    AND htly.MasterHuntTypeID = @iMasterHuntTypeID
    AND htly.LicenseYear = @iLicenseYear
    AND dt.StatusCodeID = @iDrawTicketStatusCodeID
    AND dthc.WasDrawn = @iHuntChoiceWasDrawn
    GROUP BY ha.HuntApplicationID,
    ha.PartyNumber,
    mht.[Name],
    htly.LicenseYear,
    lStatus.[Status],
    --isnull(dbo.udf_GetHuntApplicationPartyCount(ha.HuntApplicationID), 0),
    isnull(hapc.MemberCount, 0),
    won.DrawTicketID,
    dt.PreDrawNonResidentMemberCount,
    --dbo.udf_GetAvgPreferencePoints(dt.DrawTicketID),
    app.PreferencePointAverage,
    CASE
    WHEN ha.Quantity > 1 THEN NULL
    ELSE dt.PreDrawRandomNumber
    END,
    dsm.[Name],
    dt.DrawnSequence,
    dt.PreferencePointRank,
    dt.DrawID,
    dt.RandomRank
    ORDER BY htly.LicenseYear DESC,
    mht.Name,
    lStatus.[Status],
    dt.DrawID,
    PreferencePointAverage DESC,
    PreDrawRandomNumber,
    ha.PartyNumber

对应的表值函数:

  1. CREATE FUNCTION [dbo].[tvf_GetAvgPreferencePoints]
    (@DrawTicketID INT)
    RETURNS TABLE WITH SCHEMABINDING
    AS
    RETURN
    (
    SELECT TOP 1
    CONVERT(DECIMAL, dt.PreDrawPreferencePointTotal) / NULLIF(CONVERT(DECIMAL, dt.PreDrawMemberCount),0) as PreferencePointAverage
    FROM dbo.DrawTicket dt
    WHERE dt.DrawTicketID = @DrawTicketID
    )
    GO

改写后执行时间从40s降低到16s,对于倾斜列的优化速度更为明显

SQL Server标量函数改写内联表值函数优化案例的更多相关文章

  1. SQL Server进阶(六)表表达式--派生表、公用表表达式(CTE)、视图和内联表值函数

    概述 表表达式是一种命名的查询表达式,代表一个有效地关系表.可以像其他表一样,在数据处理中使用表表达式. SQL Server支持四种类型的表表达式:派生表,公用表表达式,视图和内联表值函数. 为什么 ...

  2. SQL Server 表表达式--派生表、公用表表达式(CTE)、视图和内联表值函数

    概述 表表达式是一种命名的查询表达式,代表一个有效地关系表.可以像其他表一样,在数据处理中使用表表达式. SQL Server支持四种类型的表表达式:派生表,公用表表达式,视图和内联表值函数. 为什么 ...

  3. sql server 创建内联表值函数

    表值函数就是返回table 的函数使用它可以方便的进行查询的处理 创建的代码如下: create FUNCTION returunclassfirstlist(  -- Add the paramet ...

  4. sql server的一个字符串分割的表值函数方法

    ALTER function [dbo].[BOSplit](@SourceSql nvarchar(max),  --要分割的字段@StrSeprate varchar(10)      --分割符 ...

  5. SQL Server进阶(十二)常用函数

    在SQL 2012基础教程中列出子句是按照以下顺序进行逻辑处理. FROM WHERE GROUP BY HAVING SELECT ORDER BY FROM TableName WHERE Use ...

  6. T-SQL编程 —— 用户自定义函数(内嵌表值函数)

    内嵌表值函数 接上 <T-SQL编程 -- 用户自定义函数(标量函数)> http://www.cnblogs.com/viusuangio/p/6212072.html 内嵌表值函数可以 ...

  7. inline(内联)函数

    1,为小操作定义一个函数的好处是:     a.可读性会强很多.     b.改变一个局部化的实现比更改一个应用中的300个出现要容易得多     c.函数可以被重用,不必为其他的应用重写代码     ...

  8. C++中的内联成员函数与非内联成员函数

    在C++中内联成员函数与非内联成员函数的可以分为两种情况: 1.如果成员函数的声明和定义是在一起的,那么无论有没有写inline这个成员函数都是内联的,如下: using namespace std; ...

  9. C++如何处理内联虚函数

    http://blog.csdn.net/hedylin/article/details/1775556 当一个函数是内联和虚函数时,会发生代码替换或使用虚表调用吗? 为了弄清楚内联和虚函数,让我们将 ...

随机推荐

  1. 26. Remove Duplicates from Sorted Array(代码思路新奇)

    Given a sorted array, remove the duplicates in-place such that each element appear only once and ret ...

  2. wex5 如何在js中给data添加数据

    var options = { defaultValues :[ {'xuetang' : xuetang,'time' : time} ] }; this.comp("xuetangDat ...

  3. 如何在Ubuntu上在多个PHP版本之间切换 (for swoole)

    摘要: 之前一直用Php7.0,今天想用7.2试下一些特性,安装完之后,切换回7.0却不能再使用7.0的swoole了,原来是切换方式出现了问题 一 从PHP 7.0 切换到 PHP 7.2 Apac ...

  4. CNN与图像高级应用

    一.图像识别与定位 思路1:视作回归 4个数字,用L2 loss/欧氏距离损失(x,y,w,h)这四个数都是连续值 思路2:借助图像窗口 二.物体识别 0.图像识别与定位: (1)Classifica ...

  5. String转int,int转String

    String转int 1) int i = Integer.parseInt([String]);  int i = Integer.parseInt([String],[int radix]); 2 ...

  6. MEWKit:Cryptotheft 的最新武器

    By:Yonathan Klijinsma 译者:知道创宇安全服务团队.404区块链安全团队 介绍 当谈到加密货币时,会联想到加密货币巨大的价格波动,交易违约.赎金勒索的情况以及许多不同种类的货币.虚 ...

  7. nodejs express 部署

    一.express 4.x版本之前 全局安装express 命令是 npm install express -g express 4.x版本之后 全局安装express 命令是 npm install ...

  8. git 命令解析

    git 补丁 Git 提供了两种补丁方案:   (1)用 git diff 生成的UNIX标准补丁.diff文件:.diff文件只是记录文件改变的内容,不带有commit记录信息,多个commit可以 ...

  9. nslookup 工具的使用方法记录

    查询IP地址 nslookup最简单的用法就是查询域名对应的IP地址,包括A记录和CNAME记录,如果查到的是CNAME记录还会返回别名记录的设置情况.其用法是: nslookup 域名 定查询记录类 ...

  10. Spring Data JPA基本了解

    前言 自 JPA 伴随 Java EE 5 发布以来,受到了各大厂商及开源社区的追捧,各种商用的和开源的 JPA 框架如雨后春笋般出现,为开发者提供了丰富的选择.它一改之前 EJB 2.x 中实体 B ...