在SQL Server 2000中缓存函数结果

7
我想要为了提高性能而记忆化函数结果,即懒加载一个以函数参数为索引的缓存。第一次调用函数时,缓存中没有任何输入参数的内容,因此它将计算并存储结果,然后返回它。随后的调用只需使用缓存即可。
然而,似乎 SQL Server 2000 有一个愚蠢的任意规则,限制函数必须是“确定性”的。这意味着禁止使用 INSERT、UPDATE 和常规存储过程调用。但是,允许使用扩展存储过程。这怎么是确定性的?如果另一个会话修改了数据库状态,函数输出就会发生变化。
我非常生气。我原本以为可以使缓存对用户透明。这可能吗?我没有权限部署扩展存储过程。
编辑:
这个限制在 2008 年仍然存在。你甚至不能调用 RAND 函数!
缓存将由我在数据库中实现。缓存是用于缓存的任何数据存储...
编辑:
除了基础数据的更改外,没有任何情况下相同的函数参数将产生不同的结果。这是一个商业智能平台,唯一的更改来自计划的 ETL,在那时我会 TRUNCATE 缓存表。
这些是 I/O 密集型时间序列计算,大约是 O(n^4) 的规模。我没有权利更改基础表或索引。此外,许多这些函数使用相同的中间函数,缓存允许使用它们。
UDF 并不真正是确定性的,除非它们考虑到数据库状态的更改。那有什么意义呢?SQL Server 是否具有缓存功能?(具有讽刺意味。)如果 SQL Server 具有缓存功能,则必须在绑定模式下对更改表的缓存进行过期处理。如果它们是绑定模式,则为什么不绑定函数修改的表?我可以理解为什么不允许存储过程,尽管这只是粗心;只需对存储过程进行模式绑定即可。而且,顺便说一句,为什么允许扩展存储过程?你不可能跟踪这些过程以确保确定性!!!啊!!!
编辑:
我的问题是:是否有任何方法可以懒惰地缓存函数结果,并以视图的方式使用它们?

抱歉,从您的原始帖子中我并没有清楚地了解到您是要“从头开始”创建缓存。如果同样的函数以相同的参数调用时返回不同的结果,您打算如何处理? - John Saunders
1个回答

2

确定性意味着相同的输入独立于时间和数据库返回相同的输出。

SQL Server(任何版本)不会缓存UDF - 我认为它将避免在单个行上两次调用UDF,但仅此而已。

我使用过的一个技巧是(我想我在这里发布过):

如果可以的话,请重新设计UDF,以便对于给定输入集返回有效的离散子集。 对于数字计算,有时可以重构逻辑以返回乘以外部UDF而不是从传入值内部乘以UDF的因子或比率。

对DISTINCT行集调用UDF并将结果缓存到临时表中。 如果您只使用17,000,000行集合中的100,000个参数元组调用UDF,则这非常高效。

JOIN到临时表(基本上从基于代码的逻辑转换为基于表的逻辑)以获取值。

此表可以根据需要重复使用甚至保留。

可以通过首先LEFT JOIN找到缺少的缓存条目来添加到表中。

这适用于单行表值UDF和标量UDF。 我主要将其用于表值UDF。 SQL Server 2005有一个热修复程序,可以解决UDF性能问题 - 我正在等待DBA测试它是否可以部署到生产环境中。


首先,缓存的目的是进行惰性计算。填充表格只会使其失去意义。其次,这种方法只是将缓存移出了UDF。为什么不直接跳过UDF并使用proc呢?最后,函数可以用于视图中,而视图具有procs没有的优势。 - jennykwan
我完全填充所有可能的UDF结果,而且只填充这些结果。有些结果会被多次调用,没有一个结果会被调用0次。这不是缓存,而是预计算。通过实际进行UDF调用以填充查找表的次数差异,可以直接测量节省的效果。但这样做需要权衡存储空间。 - Cade Roux

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接