问题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. 工作中常用到的JS验证

    Common.js // JavaScript Document // _ooOoo_ // o8888888o // 88" . "88 // (| -_- |) // O\ = ...

  2. C++ new、delete、namespace关键字。

    C++ 中的动态内存分配: C++与C语言分配内存关键字不同,C语言中的动态内存分配是通过 malloc(分配内存) 与 free(释放内存)完成.C++使用new(分配内存)  delete(释放内 ...

  3. centos7配置mysql8.0主从复制

    注意:1.主库:10.1.131.75,从库:10.1.131.762.server-id必须是纯数字,并且主从两个server-id在局域网内要唯一. [主节点]vi /etc/my.cnf[mys ...

  4. 常用的一些js校验

    参考:https://blog.csdn.net/xxjmlgb/article/details/49467717 var valNull;//非空校验 var valSpecial;//特殊字符校验 ...

  5. easyui,获取tabs标签页内容,以及刷新datagrid

    因为先点开tab页xxx查看表格,再点另一个tab页xxxx修改部分信息,再切换到tab页xxx,tab页xxx里的datagrid表格不会刷新,显示不了修改的信息(在此tab页按F5刷新可以解决,但 ...

  6. lnmp 中的laravel出现白屏的处理办法

    find / |grep fastcgi_params 其实是找fastcgi_params这个文件编辑 如果在知道目录的情况下也可以直接 vi /usr/local/nginx/conf/fastc ...

  7. centos7 mysql 各种报错

    1.重置root密码 vi /etc/my.cnf 添加skip-grant-tables service mysqld restart 2.mysql 登录 报错1 Unknown system v ...

  8. caffe数据集LMDB的生成

    本文主要介绍如何在caffe框架下生成LMDB.其中包含了两个任务的LMDB生成方法,一种是分类,另外一种是检测. 分类任务 第一步  生成train.txt和test.txt文件文件 对于一个监督学 ...

  9. 一、Core授权(基于cookie)

    一.Core的授权 配置 打开项目中的Startup.cs文件,找到ConfigureServices方法,我们通常在这个方法里面做依赖注入的相关配置.添加如下代码: public void Conf ...

  10. 007-SaltStack之修改salt-minion id

    1. 需求背景 之前使用saltstack添加的主机默认使用了hostname作为salt-minion id,而主机名如果没有做规范和规划,是比较难区分属于什么业务或者机器的.我们需要修改salt- ...