如何防止重新编译临时查询

How to prevent recompile for ad hoc query

当我第一次 运行 以下查询时,重新编译发生了(7 秒)。如果我 运行 它再次返回结果 <100ms。但是当我只改变数值时,它每次都坚持重新编译。

有没有一种方法可以在不使用 SP(已经过验证可以工作)的情况下防止重新编译?

set statistics time on;

declare
    @o bigint = 3374707

select * from ComplexTableValuedFunction(@o)
option (keep plan, use hint ('DISABLE_PARAMETER_SNIFFING')) -- has no effect in ad hoc?

set statistics time off;

附带问题:出于某种原因,统计信息只列出了较短的执行时间(~100 毫秒),而没有列出编译时间。 SQL Sentry 验证编译时间为~7s。

任何时候临时批更改,即使是单个字符,都会重新编译。

为防止重新编译,您需要使用 sp_executesql 传递批处理,并正确地对其进行参数化。此时,你会得到参数嗅探,除非你添加提示 'DISABLE_PARAMETER_SNIFFING'

set statistics time on;

EXEC sp_executesql
  N'
select * from ComplexTableValuedFunction(@o);
',
  N'@o bigint',
  @o = 3374707;

set statistics time off;

实际的EXEC语句没有查询计划,所以改变值不会有任何影响。

请注意,来自客户端应用程序(例如 C#/SqlClient)的参数化查询实际上使用 sp_executesql