用户定义函数性能缺点

Fis*_*ury 2 sql-server-2005 functions

我有一个包含大量 UDF 的数据库,这些 UDF 由涉及大量数据操作和计算的长时间运行的进程调用。

我使用 UDF 的想法是将信息的逻辑单元从底层表中分离出来。例如,如果我想获取有关汽车的信息,我可能有几个表,例如颜色、型号、年份等,每次获取汽车时我都必须加入这些表。相反,我将使用像 fnCar() 这样的函数来获取数据的非规范化视图。

我在长时间运行的过程中多次调用这些函数,我想知道如果我有一个非规范化的工作表、视图或临时表来进行数据操作和计算是否会更好。一般来说,使用 UDF 在性能方面是否有一些我应该注意的缺点?

例如,我使用 UDF 进行一些计算。然后,我对该数据进行逆透视并将其存储在表中。每当我需要再次使用该数据时,我都会调用 UDF 将数据转回原处。我们这样做的原因是为了保持计算的灵活性。如果我们添加/删除/更改计算,我们不想更改数据模型。

--Calculate some values in a function

declare @location table
(
    id int,
    lattitude float,
    longitude float
)

insert into @location select  1, 40.7, 74
insert into @location select  2, 42, 73
insert into @location select  3, 61, 149
insert into @location select  4, 41, 87


declare @myLattitude float
declare @myLongitude float
set @myLattitude =43
set @myLongitude = 116

declare @distance table
(
    id int,
    distance float
)

insert into @distance
select id, sqrt(power(lattitude-@mylattitude,2)+power(longitude-@mylongitude,2))
from @location



--Store unpivoted data in a table
declare @unpivot table
(
    id int,
    attribute varchar(100),
    attributeValue float
)

insert into @unpivot
(
    id,
    attribute,
    attributeValue
)
select id
    ,attribute
    ,attributevalue 
from
(
    select 
        L.id,
        L.Lattitude, 
        L.Longitude,
        D.Distance
    from @location L 
        inner join @distance D 
        on L.id=D.id
) a
unpivot 
(
    attributeValue for attribute in
    (lattitude, longitude, distance)
) x

--retrive data from store via pivoting function for reporting

select * 
from @unpivot
pivot 
(
    max(attributeValue) for Attribute in (lattitude, longitude, distance)

) x
Run Code Online (Sandbox Code Playgroud)

Wor*_*DBA 5

有时您必须决定什么对您更重要,代码的维护还是代码的运行速度?它运行缓慢的原因是 UDF 是逐行处理的 - SQL Server 使用基于集合的操作性能最佳。您没有理由不能保留 UDF,因为有时使用它们可能比扩展查询更实用。

我的建议是:如果您的数据集很小,请随意使用 UDF;但是,如果您正在处理大型数据集,那么请花时间编写、测试和优化查询以获得最佳结果 - 从长远来看,当您没有用户抱怨他们的系统速度缓慢时,这将使您受益。