代码之家  ›  专栏  ›  技术社区  ›  jennykwan

SQL Server 2000中的缓存函数结果

  •  6
  • jennykwan  · 技术社区  · 16 年前

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

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

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

    编辑:

    这一限制仍在2008年。看在上帝的份上,你不能打电话给兰德!

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

    编辑:

    除了对底层数据的更改之外,函数的相同参数不会产生不同的结果。这是一个BI平台,唯一的更改来自预定的ETL,此时我将截断缓存表。

    这些是I/O密集型时间序列计算,按O(n^4)的顺序进行。我没有权限更改基础表或索引。而且,许多这些函数使用相同的中间函数,缓存允许使用这些中间函数。

    UDF不是真正确定的,除非它们考虑到数据库状态的变化。有什么意义?是SQL Server缓存吗?(讽刺的是。)如果SQL Server正在缓存,那么它必须在对绑定到架构的表所做的更改时过期。如果它们是模式绑定的,那么为什么不绑定函数修改的表呢?我可以理解为什么不允许procs,尽管这只是草率的;只是模式绑定procs。另外,顺便问一下,为什么要允许扩展存储过程?你不可能追踪到他们做了什么来确保决定论!!! 啊!!!

    编辑:

    我的问题是:是否有任何方法可以在视图中使用惰性缓存函数结果?

    1 回复  |  直到 16 年前
        1
  •  2
  •   Cade Roux    16 年前

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

    SQL Server(任何版本)都不缓存UDF—我相信它可以避免在一行上调用两次UDF,但就是这样。

    我用过的一个技巧是(我想我把它贴在这里了):

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

    对不同的行集调用UDF并将结果缓存到临时表中。如果只调用17000000行集上有100000个参数元组的UDF,则 非常 效率更高。

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

    这张桌子可以根据需要重新使用,甚至可以保留。

    添加到表中可以通过第一个左连接来查找丢失的缓存项。

    这适用于单行表值udf和标量udf。我主要用于表值udf。有一个针对SQL Server 2005的修补程序,它应该解决UDF的性能问题——我正在等待dba在部署到生产环境之前测试它。