SQL Server计算列在简单的select语句上降低了性能

cra*_*mmy 3 sql sql-server stored-procedures calculated-columns user-defined-functions

背景:

以前,我的公司使用用户定义的函数来对存储过程的where子句中的某些数据进行html编码.示例如下:

DECLARE @LName --HTML encoded last name as input parameter from user

SELECT * 
  FROM (SELECT LName
          FROM SomeView xtra
         WHERE (( @LName <> '' 
              AND dbo.EncodingFunction(dbo.DecodingFunction(xtra.LName)) = @LName) 
           OR @Lname=''))
Run Code Online (Sandbox Code Playgroud)

我为了清楚起见简化了这一点.

问题是,当带有此查询的存储过程快速连续调用45次时,具有62,000条记录的表的平均性能大约为85秒.当我删除UDF时,性能提高到1秒以上,以便运行sproc 45次.

因此,我们咨询并决定了一个解决方案,该解决方案包括视图访问的表中的计算列SomeView.计算列被写入表定义,如下所示:

[LNameComputedColumn] AS (dbo.EncodingFunction(dbo.DecodingFunction([LName])))
Run Code Online (Sandbox Code Playgroud)

然后,我运行了一个更新表的过程,并自动为所有62,000条记录填充该计算列.然后我将存储过程查询更改为以下内容:

DECLARE @LName --HTML encoded last name as input parameter from user

SELECT * FROM
      (SELECT LNameComputedColumn
      FROM SomeView xtra
      WHERE  (( @LName <> '' AND xtra.LNameComputedColumn=@LName) OR @Lname='')
Run Code Online (Sandbox Code Playgroud)

当我运行该存储过程时,45次执行的平均运行时间增加到大约90秒.我的改变实际上使问题变得更糟!

我究竟做错了什么?有没有办法改善表现?

作为旁注,我们目前正在使用SQL Server 2000并计划很快升级到2008 R2,但所有代码都必须在SQL Server 2000中运行.

Rem*_*anu 8

添加计算会创建一个虚拟列,仍然在运行时为所选的每一行计算.你想要的是一个计算的持久化列,它在插入时计算并物理存储在表中:

[LNameComputedColumn] 
   AS (dbo.EncodingFunction(dbo.DecodingFunction([LName]))) PERSISTED
Run Code Online (Sandbox Code Playgroud)