了解查询提示
查询提示是可用于强制执行查询处理器的选项或策略,用于在执行计划中对SELECT、INSERTUPDATE或DELETE语句使用特定运算符。 查询提示会替代查询处理器可能为具有 OPTION 子句的给定查询选择的任何执行计划。
在大多数情况下,查询优化器会根据索引、统计信息和数据分布选择有效的执行计划。 数据库管理员很少需要手动干预。
可以通过将查询提示添加到查询末尾来更改查询的执行计划。 例如,如果添加到 OPTION (MAXDOP <integer_value>) 使用单个 CPU 的查询的末尾,则查询可能会使用多个 CPU(并行度),具体取决于所选值。 或者,可用于 OPTION (RECOMPILE) 确保查询每次执行时都会生成新的临时计划。
--With maxdop hint
SELECT ProductID, OrderQty, SUM(LineTotal) AS Total
FROM Sales.SalesOrderDetail
WHERE UnitPrice < $5.00
GROUP BY ProductID, OrderQty
ORDER BY ProductID, OrderQty
OPTION (MAXDOP 2)
GO
--With recompile hint
SELECT City
FROM Person.Address
WHERE StateProvinceID=15 OPTION (RECOMPILE)
GO
尽管查询提示可能为各种性能相关问题提供本地化解决方案,但出于以下原因,应避免在生产环境中使用这些提示。
- 查询时拥有永久查询提示可能会导致结构数据库更改,这对该不适用查询非常有利。
- 如果将查询绑定到特定执行计划,则无法从 SQL Server 后续版本中的新功能和改进功能中受益。
但是,SQL Server 上提供了多个查询提示,这些提示用于不同的目的。 让我们在下面讨论其中的一些内容:
FAST <integer_value>—在继续执行查询时检索前 integer_value<> 行。 它对快速查询提示的小型数据集和低值更加有效。 随着行计数的增加,查询成本会更高。OPTIMIZE FOR- 向查询优化器提供说明,指示编译和优化查询时应使用局部变量的特定值。USE PLAN— 查询优化器使用 由xml_plan 属性指定的查询计划。RECOMPILE- 为查询创建一个新的临时计划,并在执行查询后立即放弃它。{ LOOP | MERGE | HASH } JOIN——指定整个查询中的所有联接操作都由LOOP JOIN、MERGE JOIN或HASH JOIN执行。 如果指定多个联接提示,优化器将从选项中选择成本最低的联接策略。MAXDOP <integer_value>—重写sp_configure的“最大并行度”值。 指定此选项的查询也会重写资源调控器。
还可以在同一查询中应用多个查询提示。 以下示例在同一查询中使用 HASH GROUP 和 FAST <integer_value> 查询提示。
SELECT ProductID, OrderQty, SUM(LineTotal) AS Total
FROM Sales.SalesOrderDetail
WHERE UnitPrice < $5.00
GROUP BY ProductID, OrderQty
ORDER BY ProductID, OrderQty
OPTION (HASH GROUP, FAST 10);
GO
若要了解有关查询提示的详细信息,请参阅提示(Transact-SQL)。
查询存储提示
查询存储提示 提供了一种简单的方法来调整查询计划,而无需修改应用程序代码。
当查询优化器不生成有效的执行计划以及开发人员或 DBA 无法修改原始查询文本时,查询存储提示非常有用。 在某些应用程序中,查询文本可能会被硬编码或自动生成。
若要使用查询存储提示,需要标识查询语句的查询存储 query_id,你希望通过它查询存储目录视图、内置查询存储报告或 Azure SQL 数据库的 Query Performance Insight 修改。 然后,使用你想要应用于查询的 query_idsp_query_store_set_hints 和查询提示字符串执行 。
下面的示例演示如何为特定查询获取query_id,然后使用它对查询应用RECOMPILE和MAXDOP提示。
SELECT q.query_id, qt.query_sql_text
FROM sys.query_store_query_text qt
INNER JOIN sys.query_store_query q
ON qt.query_text_id = q.query_text_id
WHERE query_sql_text like N'%ORDER BY CustomerName DESC%'
AND query_sql_text not like N'%query_store%'
GO
--Assuming the query_id returned by the previous query is 42
EXEC sys.sp_query_store_set_hints @query_id= 42, @query_hints = N'OPTION(RECOMPILE, MAXDOP 1)'
GO
在某些特定情况下,查询存储提示可以帮助解决查询层面的性能问题。
- 每次执行时重新编译查询。
- 限制统计信息更新作的最大并行度。
- 使用哈希联接而不是嵌套循环联接。
- 对特定查询使用兼容性级别 110,同时使数据库保持当前兼容性。
有关查询存储提示的详细信息,请参阅 查询存储提示。