3

我有一个包含大量 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
4

1 回答 1

6

我会尝试回答

简单地说:您在使用 UDF 时做错了

当您使用 UDF 时,您会添加这些问题

  1. RBAR(见底部)处理
    当您在 SELECT 子句中使用具有表访问权限的标量 UDF 时,
    即不是有效的 JOIN,而是强制执行表查找 *per row"

  2. 使用多语句 TVF 进行黑盒处理
    每个 TVF 都必须运行完成并被视为“黑盒”

通常做的是加载一个平面暂存表,然后加入查找表,处理是作为一组完成的。如果这就是您所说的“非规范化”,那么是的,它可能效果更好。

将 UDF 用于“信息的逻辑单元”是 OO/过程思维。SQL 是基于设置的。对于在本机/CLR 代码中运行的对象或对象集合看起来正常的操作,对于通过查询优化器进行的基于集合的数据处理失败

注意:RBAR = Row By Agonizing Row。有关更多信息,请参阅Simple Talk 的文章

于 2012-08-10T14:12:23.870 回答