如何防止重新编译临时查询
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
。
当我第一次 运行 以下查询时,重新编译发生了(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
。