我正在撰写具有相当复杂的数据集,大量连接的报告。为了简化问题,并且因为我基本上是一个OO开发人员,我一直在编写很少(通常是标量)函数来完成可以通过加入子查询来完成的工作。这种事情:
SELECT
x.Name, x.userId,
... [more columns and joins]
dbo.CountOrders(x.userId)
FROM Customers x
WHERE ...
这是好习惯吗?马虎?慢?我应该编写常规 T-SQL来做这些事吗?
答案 0 :(得分:3)
我几乎从来没有一个能够进行数据访问的标量UDF。
标量UDF无法通过优化器扩展,需要进行RBAR评估。毫无疑问,这不是一个好主意。
阅读一些例子。
答案 1 :(得分:0)
在我看来,根据我的经验,内联函数不一定是邪恶的。有时候我会面临一项在没有使用功能的情况下无法实现的任务。如果您在存储过程中一遍又一遍地重复使用相同的例程,那么就像在旧的OOP中一样,您可以创建一个函数并使用它。但只是为了清洁和短代码我不建议使用函数,如果它一次性使用。 性能的提升或改进来自表索引和索引维护。只要正确创建和维护索引,内联函数就像编写普通的sql语句一样好。
答案 2 :(得分:0)
我认为在SQL中执行函数调用计算有很多危害,只要它清楚表明它们对表的用户所做的事情。你在这里所做的只是创建一个子查询的快捷方式。但是,我从不对我的主要访问查询这样做,因为人们开始“理所当然”这些类型的计算。
如果我发现我正在重复这样做,我发现制作一个以预先计算的形式包含此类信息的后备表,然后使用触发器使其保持最新更有价值。一个例子是一个数据库,我将财务摘要数据从发票行项目汇总到报价级别,然后再次汇总到提交级别(有多个引号),然后再次到策略级别(有多个)来自多个承运人的树木)。
事实证明,大多数查询确实需要策略级别的数据。通过使用触发器和汇总表,我仅仅因为工作已经完成而将一些关键查询加速了两个数量级,同时将保存的更改的性能降低了无关紧要的数量。因此,如果您发现自己在进行大量的摘要查询,请考虑一种避免工作的方法......但对于简单的情况,我认为对函数的内联调用很好。