【发布时间】:2016-05-06 00:16:02
【问题描述】:
我正在尝试为我正在创建的存储过程确定最佳方法(最快!)。这是一个相当基本的存储过程,将用于比较两个系统之间的字段以确保数据完整性。起初我想使用临时表和添加索引,但我没有看到速度上有任何差异。然后在阅读了通过表值函数获得的性能提升后,我认为这将是一种可行的方法,但一些简单的测试并没有显示出任何改进。我什至担心优化查询的原因是,由于系统之间的字段长度不匹配(另一个问题),where 条件将使用许多标量函数,所以我假设在 where 子句中执行许多标量函数对性能。
这是方法#1:
SELECT
SLXID
FROM dbo.Salesforce_Contacts a WITH(NOLOCK)
JOIN _SLX_Contact b WITH(NOLOCK)
ON a.SLXID = b.Contactid
WHERE
a.IsDeleted = 0
AND
(
LEFT(a.FirstName, 32) != b.FirstName
AND LEFT(a.LastName, 32) != b.LastName
AND LEFT(a.Title, 64) != b.Title
AND dbo.GetSLXContactStatus(a.Contact_Status__c) != b.Status
)
这是使用表值函数的方法#2:
SELECT
a.SLXID
FROM dbo.Salesforce_Contacts a WITH(NOLOCK)
JOIN _SLX_Contact b WITH(NOLOCK)
ON a.SLXID = b.Contactid
CROSS APPLY
dbo._SFContact_Functions_TEMP(a.FirstName, a.LastName, a.Title, a.Contact_Status__c) CA
WHERE
a.IsDeleted = 0
AND
(
b.FirstName != CA.FirstName_32
AND b.LastName != CA.LastName_32 -- etc.
AND b.Title != CA.Title_64
AND b.Status != CA.Contact_Status
)
这是#2中使用的表值函数:
ALTER FUNCTION dbo._SFContact_Functions_TEMP
(
@FirstName VARCHAR(40)
,@LastName VARCHAR(80)
,@Title VARCHAR(128)
,@Status VARCHAR(20)
)
RETURNS TABLE
AS
RETURN
SELECT
LEFT(@FirstName, 32) FirstName_32
,LEFT(@LastName, 32) LastName_32
,LEFT(@Title, 64) Title_64
,dbo.GetSLXContactStatus(@Status) Contact_Status
GO
最后是执行计划(实际):
【问题讨论】:
-
我更喜欢没有自定义函数的版本;它似乎更简单。但是你的问题是什么?
-
@GordonLinoff 我很可能是强迫症。查询需要 20-40 秒才能完成,这非常长(相对而言),所以我想尽可能加快速度。或许左函数等,所花费的时间是无法避免的?
标签: sql sql-server optimization user-defined-functions