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中运行.
添加计算会创建一个虚拟列,仍然在运行时为所选的每一行计算.你想要的是一个计算的持久化列,它在插入时计算并物理存储在表中:
[LNameComputedColumn]
AS (dbo.EncodingFunction(dbo.DecodingFunction([LName]))) PERSISTED
Run Code Online (Sandbox Code Playgroud)