问题SQL:

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

静态函数:

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:

改写后:

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

对应的表值函数:

​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. python3的一些文件操作的脚手架

    用python把原来的脚本重构了一下,其中写了文件操作的一些函数,如下: import os import shutil import hashlib import stat #查找文件夹中的某个文件 ...

  2. web端生成的带有echarts图表的html页面,嵌入在(javaFx)webview中显示错位问题

    web项目需要嵌入到手机APP的webview里面以及 windows客户端应用(JavaFx)的webview里面,这个时候就出现了问题. echarts渲染的时候根据浏览器不同的内核显示是有区别的 ...

  3. 解决Asp.net Core中chtml文档中文乱码的问题

    原因 由于Visual Studio 2017在保存chtml时,文本格式非utf-8,所以导致中文会出现乱码情况. 解决办法 在工具->扩展与更新中添加插件"ForceUTF8 (w ...

  4. jackson json序列化 首字母大写 第二个字母需小写

    有这样一个类: @Setter @Getter @JsonNaming(value = PropertyNamingStrategy.UpperCamelCaseStrategy.class) pub ...

  5. JDK1.8+API+中文文档+高清完整版(不要积分 免费拿)

    JDK1.8+API+中文文档+高清完整版+CHM帮助文档 链接: https://pan.baidu.com/s/1LbdWSZ4qFjWXdJ88bXkn5w 提取码: frew 希望能帮上大家的 ...

  6. 吴恩达机器学习103:SVM之大间隔分类器的数学原理

    1.向量内积: (1)假设有u和v这两个二维向量:,接下来看一下u的转置乘以v的结果,u的转置乘以v也叫做向量u和向量v的内积,u是一个二维向量,可以将其在图上画出来,如下图所示向量u: 在横轴上它的 ...

  7. 10分钟,让你彻底明白Promise原理

    什么是Promise?本代码用定外卖来举例子,让你明白. // 定外卖就是一个Promise,Promist的意思就是承诺// 我们定完外卖,饭不会立即到我们手中// 这时候我们和商家就要达成一个承诺 ...

  8. python程序超时处理 timeout_decorator

    如下两个例子,实现对某个函数的超时处理(其实就是加了一个装饰器timeout): 成功例子: 代码: import time import timeout_decorator @timeout_dec ...

  9. Delphi 标识符

  10. Wannafly挑战赛22 D 整数序列 (线段树维护三角函数值)

    链接:https://ac.nowcoder.com/acm/contest/160/D 来源:牛客网 整数序列 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语 ...