我有一个多语句表值 UDF。这会构建一个临时表,然后将其作为结果返回。
第一次执行需要 5 秒,使用相同参数的后续执行需要 1 秒。如果我更改参数,那么第一次需要 5 秒,然后又回到 1 秒。如果我然后将参数更改回第一个参数,它仍然需要一秒钟。
我无法弄清楚是什么导致它在第一次使用新参数时花费更长的时间。每次使用不同的参数时,UDF 是否会编译一个单独的查询计划?我可以在 Profiler 中监视它吗?我可以看到 sp_Recompile 事件,但我不确定 UDF 编译时触发了什么事件。
不幸的是我不能发布代码,但我希望有足够的信息让某人给我一些解释。
它不太可能与查询计划有关。我只见过每个非常复杂的查询都需要超过 1 秒的时间来创建计划,远少于您描述的 4 秒。
听起来像是页面缓存——基本上 SQL Server 将最近使用的数据保存在内存中。第一次使用每组参数运行时,您要支付(通常很昂贵的)物理磁盘访问成本。
后续执行可以访问已经存储在内存中的数据页,而无需等待磁盘子系统。
SQL Server 中的每条语句都有一个计划。语句在 UDF 或 proc 或 adhoc 中的事实通常并不重要
在这种情况下,我怀疑是缓存未命中导致了延迟。您可以通过DBCC DROPCLEANBUFFERS进行测试(注意:将影响该框上的所有进程)。编译时间适用于参数的每次更改,而不仅仅是未使用的参数。
一个想法是:UDF 处理或搅动大量数据是否足以导致缓存未命中?