T-SQL慢查询调优选项?

时间:2018-04-30 20:51:43

标签: sql sql-server tsql

使用SQL Server 2016.我正在运行以下更新查询:

update a set a.[Project Definition]=b.[Project] FROM [Table1] a 
inner join [Table2] b 
on dbo.fReplace(a.[Project Definition]) = dbo.fReplace(b. 
[PROJECT #]) 
and a.[Project Definition] <>'' 
and difference(a.[Project Description],b.[Project Name])>=3

其中[fReplace]的定义如下(它只是从一个字段中删除所有非数字字符):

CREATE function [dbo].[fReplace](@strtext varchar(2000))
returns varchar(2000)
as
begin
declare @i int = 32, @rplc varchar(1) = '';
while @i < 256
begin
    if (@i < 48 or @i > 57) and CHARINDEX(char(@i),@strtext) > 0
    begin
        --° #176 ~ 0   --¹ #185 ~ 1   --² #178 ~ 2   --³ #179 ~ 3
        set @rplc = case @i
        when 176 then '0'
        when 185 then '1'
        when 178 then '2'
        when 179 then '3'
        else '' end;

        set @strtext = REPLACE(@strtext,CHAR(@i),@rplc);
    end

    set @i = @i + 1;
end
return ltrim(rtrim(@strtext));
end

查询运行速度很慢......有什么方法可以加快速度? 请注意,我已经按上面的字段添加了索引。

此致 M.R。

2 个答案:

答案 0 :(得分:1)

在连接条件中使用函数可能会导致您的缓慢,因为它会创建一个RBAR(逐行 - 激动行)条件。 SQL Server无法将JOIN作为set操作执行,而是必须使用循环。如果您运行查询并让它返回执行计划,您很可能会看到它。

向表中添加列以保存函数的返回值将有助于加速JOIN。

答案 1 :(得分:1)

索引不会有帮助,因为您没有查找值,您正在寻找功能结果。这必须对两个表执行表扫描并运行每行的函数。如果你可以在每个表中创建一个计算列并创建一个索引,它应该加速:

ALTER TABLE Table1
ADD ComputeId AS (dbo.fReplace([Project Definition]))

CREATE INDEX Table1_ComputedIndex ON Table1 (ComputeId)