Sql server 创建计划指南

Sql server 创建计划指南,sql-server,sql-execution-plan,Sql Server,Sql Execution Plan,在SQLServer上,我正在测试创建一个计划指南,以强制来自Java的查询始终使用特定的最佳执行计划。一些SQL查询如何不使用此计划指南 我跟着 SQL来自Java declare @p1 int set @p1=1986 exec sp_prepexec @p1 output,N'@P0 nvarchar(4000)',N'SELECT Top 1 Amount,col2 from dbo.table1

在SQLServer上,我正在测试创建一个计划指南,以强制来自Java的查询始终使用特定的最佳执行计划。一些SQL查询如何不使用此计划指南

我跟着

SQL来自Java

declare @p1 int
set @p1=1986
exec sp_prepexec @p1 output,N'@P0 nvarchar(4000)',N'SELECT Top 1 Amount,col2 from dbo.table1
                                                                                 where ExId=@P0
                                                                                 order by id
                                                 ',N'0a8e8e31-2a05-0000-8ece-0003fd69e692'
select @p1
我创建的计划指南

DECLARE @xml_showplan nvarchar(max);
SET @xml_showplan = (select cast(query_plan as nvarchar(max))  from sys.dm_exec_cached_plans cp
cross apply sys.dm_exec_sql_text (cp.plan_handle) st 
cross apply sys.dm_exec_query_plan (cp.plan_handle) qp 
where st.text like '%Top 1 Amount%'
and objtype='Prepared')

--select (@xml_showplan)



EXEC sp_create_plan_guide
@name = N'ForceuserLoanAmountRequests',
@stmt = N'SELECT Top 1 Amount,col2 from dbo.table1 where ExId=@P0 order by id', 
@type = N'SQL',
@module_or_batch = NULL,
@params = N'@P0 nvarchar(4000)',
@hints = @xml_showplan;
如果您能帮助我阅读java中SQL查询使用的计划指南,我将不胜感激

使用从SQL事件探查器收集的SQL创建了计划指南

EXEC sp_create_plan_guide
@name = N'ForceuserLoanAmountRequests',
@stmt = N'SELECT Top 1 Amount,col2 from table1
                                                                                 where ExId=@P0
                                                                                 order by ID
                                                 ',
@type = N'SQL',
@module_or_batch = NULL,
@params = N'@P0 nvarchar(4000)',
@hints = @xml_showplan;

GO
请阅读文章并注意备注:

计划指南匹配要求

对于指定@type='SQL'或@type='TEMPLATE'的计划指南 成功匹配查询、批处理文本和 @参数名称数据类型[,…n]必须以正确的格式提供 与申请提交的副本格式相同。 意味着您必须提供与SQL Server完全相同的批处理文本 编译器收到它。要捕获实际批次和参数文本, 您可以使用SQL Server探查器。有关更多信息,请参阅使用SQL 用于创建和测试计划指南的服务器探查器

这意味着语句应该与您的
计划指南
中所写的内容完全匹配,但是在您的代码计划指南中,创建的语句与java发送的语句不同:它只有一行,而
java
代码有4行,带有
CR
和额外的空格

如果您评估
java
语句中的任何哈希值,以及
sp\u create\u plan\u guide
中提供的语句,您会发现它们是不同的


另一件我怀疑可能是错误的事情是你如何得到一个“好计划”。由于您只需分配可生成多行的查询结果,因此我不确定您是否获得了所需的计划。您如何确保捕获“好的计划,与java代码生成的计划不同?

我使用SQL Server Profiler运行了一个跟踪,并从性能类别中选择事件计划指南Successful和计划指南Successful,为了检查这个来自Java代码的SQL是否使用了计划指南,并且每次执行这个SQL时都不会触发这些事件,我尝试创建与Java传递到SQL Server完全匹配的with SQL语句,通过探查器收集。我的原始问题的PFA。还有一个问题是“好计划”,目前这个查询使用的是最优计划,所以收集到了@xml\u showPlan抱歉,有一件事我不明白。你说:“目前这个查询使用的是最优计划”,那么为什么你认为它没有使用计划指南呢?我想我对最初的问题陈述不是很清楚。让我试着澄清一下,有时高效运行的查询使用了正确的计划,随着时间的推移,当缓存被清除时,它会得到非最佳计划。我知道我们应该更新这类问题的统计数据。但是,由于它是一个开发环境,因此没有维护任务。因此,为了解决这个问题,我创建了一个计划指南,当查询以最优执行计划运行时,当它出于任何原因获得次优计划时,我希望它通过计划指南使用最优执行计划。希望我现在清楚了,如果有疑问请告诉我。很高兴回答您的查询有一个参数,所以您的问题是参数嗅探。我的意思是,对于不同的参数,可以建立不同的计划。清除缓存后,将为第一次执行时到达的参数生成计划。如果它是典型参数,则称该计划为最优计划,因为它适用于大多数可能的情况;如果该参数为非典型参数,则适用于该参数的计划也将用于其他参数,这正是您要防止的。您可以向代码中添加重新编译选项,或者为(@P0=…)优化选项,以始终获得最佳计划每次执行重新编译都不好,因为此SQL运行非常频繁,并且还带有查询提示,因为您将优化限制为一个参数。实际上,在这种情况下,我们应该使用Optimize for None。无论哪种方式,这都需要更改代码。我可以通过实施最优计划来解决所有这些问题