查询存储是 SQL Server 中最强大的数据库范围功能之一,用于解决性能问题并提高数据库工作负载的稳定性,自 SQL Server 2016 发布以来,我们一直在对该技术进行投资。
查询存储通常被描述为 SQL Server 的“飞行记录器”,使 SQL Server 能够在数据库范围内存储查询文本、查询计划和查询性能历史记录,以进行故障排除和性能分析。查询存储还提供了一种方法来强制查询将使用哪个计划,这是一种允许数据库管理员 (DBA) 在查询性能不佳的情况下被动地选择更健康的计划的功能。
控制查询将使用哪些计划的能力使得响应不良查询行为变得更加容易,并为数据库管理员提供了一种安全和舒适的方法来升级到更高版本的 SQL Server、更改数据库兼容性级别以及自信地将数据库应用程序迁移到云。
在之前的默认查询存储博客中,我们介绍了如何默认为 SQL Server 2022 上创建的新数据库启用查询存储。
因此,在SQL Server 2022中,我们将利用 Query Store 存储与查询相关的元数据的能力,以提供几个强大的新功能。
我们将在本系列中讨论的第一个特性是存储和持久化 Query Store 提示的能力,它为排除故障和稳定应用程序的数据库性能提供了一种新方法,而无需更改应用程序的一行代码。
事实上,您甚至可以使用查询存储提示,而无需更改您的数据库兼容级别。
因此,我们不仅可以使用 Query Store 选择更健康的计划,而且现在我们可以专门将提示应用于存储在 Query Store 中的查询,以解决目标问题或调用特定响应。
影响查询计划行为
在我们进入查询存储提示之前,我们应该回顾一下当前用于影响查询计划行为的查询提示的概念。出于多种原因,我们中的许多人已经在代码中利用提示,例如,强制索引或重新编译以缓解不稳定的查询计划。查询提示是通过OPTION子句指定的,而查询提示有助于为与性能相关的问题提供解决方案,但它们确实需要更改查询文本,这意味着我们必须更改应用程序的代码。
为什么要更改查询计划行为?
理想情况下,查询优化器会为查询选择最佳执行计划。这就是它的设计目的——但这并不总是发生。在这些情况下,DBA 可能需要针对特定条件进行优化,否则我们会陷入糟糕的计划,而糟糕的计划通常会导致糟糕的性能。
例如,我们可能有一个存储过程,其中SELECT的基数变化很大,导致您需要使用RECOMPILE提示。您可能需要限制批量插入操作的内存授予大小,您可能需要限制在与关键在线事务处理环境相同的系统上运行的报告的最大并行度,甚至使用较低的特定查询的数据库兼容性级别,以防止必须降低数据库的兼容性级别,因为您正在实现更高db_compat级别的其他好处。
简而言之,您可能需要影响计划行为的原因有很多。

在上面显示的示例中,我们使用查询提示来禁止批处理模式,并告诉 SQL Server 在每次执行时重新编译查询。很明显,这些有针对性的方法可能有助于解决特定问题,但同样需要更改代码。
大多数但不是所有查询提示都支持作为查询存储提示。可用的查询提示记录在sys.sp_query_store_set_hints.
今天应用查询提示
利用查询提示的原因有很多,但它们需要对应用程序查询进行更改,这通常是在没有应用程序所有者/供应商支持的情况下无法完成的。
数据库管理员可能并不总是能够直接对 T-SQL 代码进行这些更改。对于许多生产环境来说都是如此,并且绝对是基于供应商的收缩包装解决方案的情况。
对于正在寻找一种直接且安全的方式来影响查询行为而不更改应用程序代码的 DBA 来说,选择并不多。以前,他们不得不依赖 计划指南,而众所周知,这些指南很难使用。
什么是查询存储提示?

查询存储提示为开发人员和 DBA 提供了一种直接的方法来制定查询计划,而无需更改应用程序代码。
查询存储提示是一项扩展查询存储功能的新功能,但这意味着查询存储提示确实需要启用查询存储功能,并且您的查询和查询计划会在查询存储中捕获。
就像计划指南一样,查询存储提示是持久的,并且会在重新启动后继续存在,但查询存储提示比计划指南更易于使用。
查询存储提示会覆盖其他硬编码的语句级提示和计划指南。
查询稳定性很重要,因此使用查询存储提示,查询将始终执行,因为相反的查询存储提示将被忽略。例如,要知道的一件事是RECOMPILE提示与在数据库级别设置的强制参数化不兼容,但这不会导致查询失败。
如果数据库已强制参数化设置,并且RECOMPILE提示是查询存储中为查询设置的提示字符串的一部分,则 SQL Server 将忽略RECOMPILE提示,并在利用它们时应用任何其他提示。

使用查询存储提示
查询存储提示的生命周期遵循以下基本步骤:
- 首先,必须执行查询。
- 然后将查询、计划和执行详细信息捕获到查询存储中。这取决于当前的查询存储捕获策略,可以使用QUERY_CAPTURE_POLICY进行自定义。
- DBA 使用sp_query_store_set_hints在查询上创建查询存储提示。
- 使用查询存储提示执行查询。
要使用查询存储提示,请执行以下操作:
- 确定要修改的查询语句的查询存储query_id 。您可以通过多种方式执行此操作:
- 查询 Query Store 目录视图。
- 使用 SQL Server Management Studio 内置的查询存储报告。
- 使用 Azure SQL 数据库的 Azure 门户“查询性能洞察”。
- 使用您希望应用于查询
sp_query_store_set_hints的query_id和查询提示字符串执行。
查询提示字符串可以包含一个或多个查询提示,如下例所示:
|
查询存储提示覆盖硬编码语句级别提示和现有计划指南提示。
数据库管理员可以sp_query_store_clear_hints通过传入@query_id来清除提示。
如果特定query_id不存在查询存储提示,则将创建新的查询存储提示,并且如果特定query_id已存在查询存储提示,则提供的最后一个值将覆盖先前为关联查询指定的值。
如果query_id不存在,则会引发错误,因为查询存储中必须存在该查询。
如果查询提示与查询优化的可能性相矛盾,则提示不会阻止查询执行并且不会应用提示。在提示会导致查询失败的情况下,提示会被忽略,最新的失败详情可以在 sys.query_store_query_hints中查看。
您可以使用以下查询查看当前的查询存储提示sys.query_store_query_hints并查看任何失败:
|
应用提示时,执行计划 XML 属性将以 XML 格式显示在执行计划的StmtSimple元素中。这些 XML 元素可通过 Transact-SQL 命令SET STATISTICS XML和SET SHOWPLAN XML的输出获得。
将QueryStoreStatementHintText显示已应用于查询的实际查询存储提示,QueryStoreStatementHintId将显示查询提示的唯一标识符,并将显示QueryStoreStatementHintSource查询存储提示的来源(例如:“用户”)。
下一步
“默认开启”查询存储只是迁移到 SQL Server 2022 的众多好处之一。
如果您尚未下载最新版本的 SQL Server 2022,请查看 SQL Server 2022 概述和新增功能参考。此版本中添加了许多新特性和改进的功能。
学到更多
有关更多信息并开始使用,请查看以下参考:
其他有用的资源:
原文标题:Query Store hints in SQL Server 2022
原文作者: David Pless
原文链接:https://cloudblogs.microsoft.com/sqlserver/2022/09/08/query-store-hints-in-sql-server-2022/




