【问题标题】:Caching Function Results in SQL Server 2000SQL Server 2000 中的缓存函数结果
【发布时间】:2010-10-12 18:42:31
【问题描述】:

我想记住函数结果以提高性能,即延迟填充函数参数索引的缓存。第一次调用函数时,缓存不会有任何输入参数,因此它会在返回之前计算并存储它。后续调用只使用缓存。

然而,SQL Server 2000 似乎有一个愚蠢的任意规则,即函数是“确定性的”。禁止插入、更新和常规存储过程调用。但是,允许扩展存储过程。这是如何确定的?如果另一个会话修改了数据库状态,函数输出无论如何都会改变。

我快疯了。我曾认为我可以使缓存对用户透明。这可能吗?我没有部署扩展存储过程的权限。

编辑:

这个限制还在 2008 年。看在上帝的份上,你不能打电话给 RAND!

缓存将由我在数据库中实现。缓存是用于缓存的任何数据存储...

编辑:

除了对基础数据的更改之外,没有任何情况下函数的相同参数会产生不同的结果。这是一个 BI 平台,唯一的变化来自预定的 ETL,那时我会 TRUNCATE 缓存表。

这些是 I/O 密集型时间序列计算,数量级为 O(n^4)。我无权更改基础表或索引。此外,其中许多函数使用相同的中间函数,并且缓存允许使用这些函数。

UDF 并不是真正的确定性,除非它们考虑到数据库状态的变化。重点是什么? SQL Server 是否缓存? (具有讽刺意味。)如果 SQL Server 正在缓存,那么它必须在对模式绑定的表进行更改时到期。如果它们是模式绑定的,那么为什么不绑定函数修改的表呢?我可以理解为什么不允许使用 proc,尽管这很草率;只是模式绑定过程。而且,顺便说一句,为什么允许扩展存储过程?你不可能追踪那些为确保确定性所做的事情!!!啊!!!

编辑:

我的问题是:有什么办法可以在视图中使用延迟缓存函数结果吗?

【问题讨论】:

  • 抱歉,从您的原始帖子中我不清楚您是“从头开始”创建缓存的。您打算如何处理具有相同参数的相同函数应该返回不同结果的情况?

标签: sql-server caching sql-server-2000


【解决方案1】:

确定性意味着相同的输入返回相同的输出,与时间和数据库无关。

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

我使用的一个技巧是(我想我在 SO 上发布了它):

如果可以的话,重构 UDF,以便为给定的一组输入有效地返回一个可用的离散值子集。对于数值计算,有时可以重构逻辑以返回在 UDF 外部相乘的因子或比率,而不是在 UDF 内部从传入的值相乘。

通过 DISTINCT 行集调用 UDF 并将结果缓存到临时表中。如果您仅在 17,000,000 行集上调用具有 100,000 个参数元组的 UDF,那么这非常效率要高得多。

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

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

可以通过第一次 LEFT JOINing 来查找丢失的缓存条目来添加到表中。

这适用于单行表值 UDF 和标量 UDF。我主要将它用于表值 UDF。 SQL Server 2005 有一个修补程序,它应该解决 UDF 性能问题 - 我正在等待 mthe DBA 在部署到生产之前对其进行测试。

【讨论】:

  • 首先缓存的重点是惰性计算。用更多的东西填充桌子会破坏目的。其次,这种方法所做的只是将缓存移出 UDF。为什么不直接使用跳过 UDF 并使用 proc?最后,可以在视图中使用函数,这具有 proc 所没有的优势。
  • 我完全填充所有且仅填充潜在的 UDF 结果。有些会被调用不止一次,没有一个会被调用 0 次。它不是缓存——它是一个预计算。通过实际为填充查找表而进行的 UDF 调用的差异可以直接衡量节省的成本。权衡是存储。
猜你喜欢
  • 2012-09-14
  • 2017-04-29
  • 2010-11-13
  • 1970-01-01
  • 1970-01-01
  • 2013-05-13
  • 1970-01-01
  • 2011-10-30
  • 2011-01-14
相关资源
最近更新 更多