sal*_*sal -3 sql-server optimization
我被检查的性能OPTION(RECOMPILE)和OPTION(FAST n)及其行为有着惊人的不同。OPTION(FAST n)那么快得多OPTION(RECOMPILE)。难道OPTION(FAST n)?每次都创建新的执行计划?
这些提示有不同的目的:
OPTION(FAST n)指定查询针对快速检索第一个 number_rows 进行了优化
它不是为了每次都生成最佳计划而设计的,而是简单地诱导优化器“认为”结果基数小于实际基数。所以这个提示与“参数嗅探”无关,它的目标不同于为给定查询生成最佳计划。
OPTION(RECOMPILE)告诉服务器不要为给定的查询缓存 pan。这意味着同一查询的另一次执行将需要制定一个新的(可能不同的)计划。这用于带参数的查询中以防止出现parameter sniffing问题。这意味着您的查询应该根据提供的参数有不同的计划。例如,当您对某个国家/地区的首都查询 smth 过滤时,您的查询几乎会返回 table 中的所有记录,并且scan在这种情况下您更喜欢 table 。但是当你过滤小城市时,你会得到几行并且更喜欢index seek+ lookup。
如果您不使用OPTION(RECOMPILE),则您的参数化查询第一次执行其参数时将“嗅探”并根据此参数值制定计划。具有不同参数的后续执行将始终使用相同的计划,这对您来说可能是不可接受的。因此,在这种情况下,您使用OPTION(RECOMPILE)将导致在每次查询执行时对结果集进行最佳基数估计。
概括。
的使用OPTION(FAST n)通常不会导致最佳计划阐述,并且会引起结果集等于 n 的固定(和错误)基数估计。
使用OPTION(RECOMPILE)一般将导致最佳计划选择,并将在每次查询执行时提供不同的(通常是正确的)基数估计,每次都基于提供的参数值。
更新
此重现显示使用 RECOMPILE 选项的查询如何不缓存其计划:
declare @prod_n nvarchar(255) = N'HJ-1428'
select * /*4042FBFE-6ED4-406E-90F8-73C5EBD3920F*/
from [Production].[Product]
where ProductNumber = @prod_n
option(recompile);
declare @sql nvarchar(4000);
set @sql =
N'select * /*4042FBFE-6ED4-406E-90F8-73C5EBD3920F*/
from [Production].[Product]
where ProductNumber = @prod_n
option(recompile);'
exec sp_executesql @sql, N'@prod_n nvarchar(255)',@prod_n;
select *
from sys.dm_exec_query_stats qs
cross apply sys.dm_exec_sql_text(qs.plan_handle) qt
cross apply sys.dm_exec_query_plan(qs.plan_handle) qp
where qt.text like '%4042FBFE-6ED4-406E-90F8-73C5EBD3920F%'
and qt.text not like '%sys.dm_exec_query_stats%'; -- uncomment this to get the plan for given query that looks for the plan
Run Code Online (Sandbox Code Playgroud)
这里我使用guid来区分我的查询,并且我使用and qt.text not like '%sys.dm_exec_query_stats%'条件排除寻找前两个查询的计划的最后一个查询的计划。
我在查询中同时使用了局部变量和参数,但没有一个将计划放入缓存中。
| 归档时间: |
|
| 查看次数: |
12812 次 |
| 最近记录: |