..
第一个解决方案是在查询中使用JOIN直接重写如下
SELECT PC.LastName + '' + PC.FirstName [客户名称]
,SC.CustomerType
从Sales.Customer SC
LEFT OUTER JOIN YES Sales.Individual
ON = SC.CustomerID SI.CustomerID
LEFT OUTER JOIN Person.Contact资料PC
ON = SI.ContactID PC.ContactID
在这第二个版本我只是用在函数的GetName表将在FROM子句中的。 我也取代对在SELECT语句中的列清单,直接串联两列的表中的函数调用联系的GetName。
下面是探查显示,执行这项查询

正如你可以看到从以前的版本无数的电话查询面对,新版本是一个单一的通话,这当然是指在性能方面大省。
现在让我们看看通过转换函数返回一个表,而不是(内联表)原标量函数的GetName发生。 首先,创建函数和denominiamola GetNameTable
CREATE FUNCTION GetNameTable(@客户ID INT) 返回表 AS (RETURN SELECT姓氏+','+名字[客户名称] 从Sales.Customer SC LEFT OUTER JOIN YES Sales.Individual ON = SC.CustomerID SI.CustomerID LEFT OUTER JOIN Person.Contact资料PC ON = SI.ContactID PC.ContactID WHERE的CustomerID = @ SC.CustomerID )
正如你可以看到查询,提取数据,等于标量函数的GetName的,唯一不同的是,函数返回一个varchar值表GetNameTable代替。 要使用这项新功能,他采用的是需要使用CROSS APPLY如下操作
选择一[客户名称]
,SC.CustomerType
从Sales.Customer SC
CROSS APPLY GetNameTable(SC.CustomerID)的
在这种情况下,下面的结果将探查

让我们来看看如何编写原始查询更有效的最后一个例子。 这一次,我们将创建并使用下面的观点
CREATE VIEW View_GetName
AS
SELECT姓氏+','+名字[客户名称]
,SC.CustomerID
从Sales.Customer SC
JOIN THE Sales.Individual
ON = SC.CustomerID SI.CustomerID
JOIN Person.Contact资料PC
ON = SI.ContactID PC.ContactID
GO
基于这一观点,我们可以写我们的查询,如下所示
五,选择[客户名称]
,CustomerType
从Sales.Customer SC
LEFT OUTER JOIN View_GetName V
ON SC.CustomerID的CustomerID = R.
在这种情况下,探查结果等于前两个例子。 这三个例子是等价的,虽然在性能上呈现小的差异。 最有效的方法是CROSS JOIN在稍低的CPU使用率造成(可从Profiler中的数据看出)。
这些例子是为了强调,在SELECT语句中或在WHERE子句是一个低效率的做法列列表使用标量函数。 这种做法的负面影响是成正比的,从所使用的查询提取的数据量。 当以这种方式使用,标量函数的行为就像一个被反复调用游标,然后权衡下来,我们的指示发展。 因此,如果在您的查询的一些考虑使用标量函数来改写的建议的替代的相同。
在本文中看到的这些只是可能的措施,以改善我们的T - SQL查询和其他一些有用的设备的性能将在未来的文章中讨论。