Skip to content

Commit a682bf1

Browse files
Merge pull request #34802 from dimitri-furman/dfurman/qds-hints-by-query-hash
Update QDS hints
2 parents 82c276c + c8c326b commit a682bf1

File tree

5 files changed

+170
-141
lines changed

5 files changed

+170
-141
lines changed
Lines changed: 47 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
---
2-
title: "Query Store hints best practices"
2+
title: "Query Store Hints Best Practices"
33
description: "Best practices for the Query Store hints feature, which helps you to shape query plans without changing application code."
44
author: MikeRayMSFT
55
ms.author: mikeray
6-
ms.date: 04/04/2025
6+
ms.reviewer: randolphwest
7+
ms.date: 07/25/2025
78
ms.service: sql
89
ms.subservice: performance
910
ms.topic: best-practice
@@ -21,26 +22,26 @@ monikerRange: "=azuresqldb-current || =azuresqldb-mi-current || >=sql-server-ver
2122

2223
This article details best practices for using [Query Store hints](query-store-hints.md). Query Store hints enable shaping query plan shapes without modifying application code.
2324

24-
- For more information on configuring and administering with the Query Store, see [Monitoring performance by using the Query Store](monitoring-performance-by-using-the-query-store.md).
25-
- For information on discovering actionable information and tune performance with the Query Store, see [Tuning performance by using the Query Store](tune-performance-with-the-query-store.md).
26-
- For general best practices on the Query Store, see [Best practices with Query Store](best-practice-with-the-query-store.md).
25+
- For more information on configuring and administering with the Query Store, see [Monitor performance by using the Query Store](monitoring-performance-by-using-the-query-store.md).
26+
- For information on discovering actionable information and tune performance with the Query Store, see [Tune performance with the Query Store](tune-performance-with-the-query-store.md).
27+
- For general best practices on the Query Store, see [Best practices for monitoring workloads with Query Store](best-practice-with-the-query-store.md).
2728

2829
## Use cases for Query Store hints
2930

3031
Consider the following use cases as ideal of Query Store hints. For more information, see [When to use Query Store hints](query-store-hints.md#when-to-use-query-store-hints).
3132

32-
> [!CAUTION]
33-
> Because the SQL Server Query Optimizer typically selects the best execution plan for a query, we recommend only using hints as a last resort for experienced developers and database administrators. For more information, see [Query Hints](../../t-sql/queries/hints-transact-sql-query.md).
33+
> [!CAUTION]
34+
> Because the SQL Server Query Optimizer typically selects the best execution plan for a query, we recommend only using hints as a last resort for experienced developers and database administrators. For more information, see [Query hints](../../t-sql/queries/hints-transact-sql-query.md).
3435
3536
### When code cannot be changed
3637

37-
Using Query Store hints allows you to influence the execution plans of queries without changing application code or database objects. No other feature allows for you to apply query hints quickly and easily.
38+
Using Query Store hints allows you to influence the execution plans of queries without changing application code or database objects. No other feature allows for you to apply query hints quickly and easily.
3839

39-
You can use Query Store hints, for example, to benefit ETL without redeploying code. Learn how to improve bulk loading with Query Store hints with this 14-minute video:
40+
You can use Query Store hints, for example to benefit extract-transform-load (ETL) workloads, without redeploying code. Learn how to improve bulk loading with Query Store hints with this 14-minute video:
4041

4142
> [!VIDEO https://channel9.msdn.com/Shows/data-exposed/using-query-store-hints-to-optimize-memory-grants-improving-performance/player?WT.mc_id=dataexposed-c9-niner]
4243
43-
Query Store hints are lightweight query tuning methods, but if a query becomes problematic it should be addressed with more substantial code changes. If you are regularly finding the need to apply Query Store hints to a query, consider a larger query rewrite. The SQL Server Query Optimizer typically selects the best execution plan for a query. We recommend only using hints as a last resort for experienced developers and database administrators.
44+
Query Store hints are lightweight query tuning methods, but if a query becomes problematic it should be addressed with more substantial code changes. If you're regularly finding the need to apply Query Store hints to a query, consider a larger query rewrite. The SQL Server Query Optimizer typically selects the best execution plan for a query. We recommend only using hints as a last resort for experienced developers and database administrators.
4445

4546
For information on which query hints can be applied, see [Supported query hints](../system-stored-procedures/sys-sp-query-store-set-hints-transact-sql.md#supported-query-hints).
4647

@@ -52,17 +53,17 @@ Query Store hints can be added and removed to batches of queries to adjust perfo
5253

5354
### As a replacement for plan guides
5455

55-
Previous to Query Store hints, a developer would have to rely on [plan guides](plan-guides.md) to accomplish similar tasks, which can be complex to use. Query Store hints are integrated with Query Store features of SQL Server Management Studio (SSMS), for visual exploration of queries.
56+
Previous to Query Store hints, a developer would have to rely on [plan guides](plan-guides.md) to accomplish similar tasks, which can be complex to use. Query Store hints are integrated with Query Store features of SQL Server Management Studio (SSMS), for visual exploration of queries.
5657

57-
With plan guides, searching through all plans using query snippets is necessary. The Query Store hints feature does not require exact matching queries to impact the resulting query plan. Query Store hints can be applied to a `query_id` in the Query Store dataset.
58+
With plan guides, searching through all plans using query snippets is necessary. The Query Store hints feature doesn't require exact matching queries to impact the resulting query plan. Query Store hints can be applied to a `query_id` in the Query Store dataset.
5859

59-
Query Store hints override hard-coded statement-level hints and existing plan guides.
60+
Query Store hints override hard-coded statement-level hints and existing plan guides.
6061

6162
### Consider a newer compatibility level
6263

63-
Query Store hints can be a valuable method when a newer database compatibility level is not available to you due to vendor specification or larger testing delays, for example. When a higher compatibility level is available to a database, consider upgrading the database compatibility level of an individual query to take advantage of the latest performance optimizations and features of SQL Server.
64+
Query Store hints can be a valuable method when a newer database compatibility level isn't available to you due to vendor specification or larger testing delays, for example. When a higher compatibility level is available to a database, consider upgrading the database compatibility level of an individual query to take advantage of the latest performance optimizations and features of SQL Server.
6465

65-
For example, if you have a [!INCLUDE[sssql22-md](../../includes/sssql22-md.md)] instance with a database in compatibility level 140, you can still use Query Store hints to run individual queries in compatibility level 160. You could use the following hint:
66+
For example, if you have a [!INCLUDE [sssql22-md](../../includes/sssql22-md.md)] instance with a database in compatibility level 140, you can still use Query Store hints to run individual queries in compatibility level 160. You could use the following hint:
6667

6768
```sql
6869
EXEC sys.sp_query_store_set_hints @query_id= 39, @query_hints = N'OPTION(USE HINT(''QUERY_OPTIMIZER_COMPATIBILITY_LEVEL_160''))';
@@ -72,18 +73,18 @@ For a complete tutorial, see [Query Store hints Examples](query-store-hints.md#e
7273

7374
### Consider an older compatibility level after upgrade
7475

75-
Another case where Query Store hints can help is where queries cannot be modified directly after a SQL Server instance migration or upgrade. Use Query Store hints to apply a prior compatibility level for a query until it can be rewritten or otherwise addressed to perform well in the latest compatibility level. Identify outlier queries that regressed with a higher compatibility level using the [Query Store's regressed queries report](monitoring-performance-by-using-the-query-store.md#Regressed), using the [Query Tuning Advisor](upgrade-dbcompat-using-qta.md) tool during a migration, or other query-level application telemetry. For more information on the differences between compatibility levels, review the [Differences between compatibility levels](../../t-sql/statements/alter-database-transact-sql-compatibility-level.md#differences-between-compatibility-levels).
76+
Another case where Query Store hints can help is where queries can't be modified directly after a SQL Server instance migration or upgrade. Use Query Store hints to apply a prior compatibility level for a query until it can be rewritten or otherwise addressed to perform well in the latest compatibility level. Identify outlier queries that regressed with a higher compatibility level using the [Query Store's regressed queries report](monitoring-performance-by-using-the-query-store.md#Regressed), using the [Query Tuning Assistant](upgrade-dbcompat-using-qta.md) tool during a migration, or other query-level application telemetry. For more information on the differences between compatibility levels, review the [Differences between compatibility levels](../../t-sql/statements/alter-database-transact-sql-compatibility-level.md#differences-between-compatibility-levels).
7677

7778
After performance testing the new compatibility level and deploying Query Store hints in this way, you can upgrade the entire database's compatibility level while keeping key problematic queries on the prior compatibility level, without any code changes.
7879

7980
### Block future execution of problematic queries
8081

81-
You can use the `ABORT_QUERY_EXECUTION` query hint to block future execution of known problematic queries, for example nonessential queries causing high resource consumption and impacting critical application workloads.
82+
You can use the `ABORT_QUERY_EXECUTION` query hint to block future execution of known problematic queries, for example nonessential queries causing high resource consumption and affecting critical application workloads.
8283

83-
> [!NOTE]
84+
> [!NOTE]
8485
> At this time, the [ABORT_QUERY_EXECUTION](/sql/t-sql/queries/hints-transact-sql-query?view=azuresqldb-current&preserve-view=true#use_hint_abort_query_execution) (preview) query hint is available only in [!INCLUDE [ssazure-sqldb](../../includes/ssazure-sqldb.md)] and [!INCLUDE [sql-server-2025](../../includes/sssql25-md.md)].
8586
86-
For example, to block future execution of `query_id` 39, execute the following statement:
87+
For example, to block future execution of `query_id` 39, execute [sys.sp_query_store_set_hints](../system-stored-procedures/sys-sp-query-store-set-hints-transact-sql.md) as follows:
8788

8889
```sql
8990
EXEC sys.sp_query_store_set_hints
@@ -98,20 +99,24 @@ The following considerations apply:
9899
- When you specify this hint for a query, an attempt to execute the query fails with error 8778, severity 16, *Query execution has been aborted because the ABORT_QUERY_EXECUTION hint was specified.*
99100
- To unblock a query, you can clear the hint by passing the `query_id` value to the `@query_id` parameter in the [sys.sp_query_store_clear_hints](../system-stored-procedures/sys-sp-query-store-clear-hints-transact-sql.md) stored procedure.
100101
- You can use system views to find queries in Query Store that are blocked, as in the following example query:
101-
```sql
102-
SELECT qsh.query_id,
103-
q.query_hash,
104-
qt.query_sql_text
105-
FROM sys.query_store_query_hints AS qsh
106-
INNER JOIN sys.query_store_query AS q
107-
ON qsh.query_id = q.query_id
108-
INNER JOIN sys.query_store_query_text AS qt
109-
ON q.query_text_id = qt.query_text_id
110-
WHERE UPPER(qsh.query_hint_text) LIKE '%ABORT[_]QUERY[_]EXECUTION%'
111-
```
102+
103+
```sql
104+
SELECT qsh.query_id,
105+
q.query_hash,
106+
qt.query_sql_text
107+
FROM sys.query_store_query_hints AS qsh
108+
INNER JOIN sys.query_store_query AS q
109+
ON qsh.query_id = q.query_id
110+
INNER JOIN sys.query_store_query_text AS qt
111+
ON q.query_text_id = qt.query_text_id
112+
WHERE UPPER(qsh.query_hint_text) LIKE '%ABORT[_]QUERY[_]EXECUTION%'
113+
```
114+
112115
- To get the `query_id` value, at least one query execution must be recorded in Query Store. This execution doesn't have to be successful. This means that future execution of timed out or canceled queries can be blocked.
116+
117+
- If you need to block or unblock all queries with a specific query hash, consider using an automation script. For example, [dbo.sp_query_store_modify_hints_by_query_hash](https://github.com/microsoft/sql-server-samples/blob/master/samples/features/query-store/sp_query_store_modify_hints_by_query_hash.sql) is a sample stored procedure that calls the `sys.sp_query_store_set_hints` or `sys.sp_query_store_clear_hints` system stored procedure in a loop for all `query_id` values matching a query hash.
113118
- If a query is already executing when you block it, its execution continues. You can use the [KILL](../../t-sql/language-elements/kill-transact-sql.md) statement to abort the query.
114-
- Execution of killed queries isn't recorded in Query Store. If the query isn't yet in Query Store, you need to let the query complete or time out to get a `query_id` that you can block.
119+
- Execution of killed queries isn't recorded in Query Store. If the query isn't yet in Query Store, you need to let the query complete or time out to get a `query_id` that you can block.
115120
- When a query is blocked by the `ABORT_QUERY_EXECUTION` hint, the `execution_type` and `execution_type_desc` columns in the [sys.query_store_runtime_stats](../system-catalog-views/sys-query-store-runtime-stats-transact-sql.md) view are set to 4 and **Exception** respectively.
116121
- As with all Query Store hints, you need to have the `ALTER` permission on the database to set and clear the `ABORT_QUERY_EXECUTION` hint.
117122

@@ -121,33 +126,33 @@ Consider the following scenarios when deploying Query Store hints.
121126

122127
### Data distribution changes
123128

124-
Plan guides, forced plans via the Query Store, and Query Store hints override the optimizer's decision making. The Query Store hint may be beneficial now, but not in the future. For example, if a Query Store hint helps a query in previous data distribution, it may be counter-productive if large-scale DML operations change the data. A new data distribution may cause the optimizer to make a better decision than the hint. This scenario is the most common consequence of forcing plan behavior.
129+
Plan guides, forced plans via the Query Store, and Query Store hints override the optimizer's decision making. The Query Store hint might be beneficial now, but not in the future. For example, if a Query Store hint helps a query in previous data distribution, it might be counter-productive if large-scale DML operations change the data. A new data distribution might cause the optimizer to make a better decision than the hint. This scenario is the most common consequence of forcing plan behavior.
125130

126-
### Regularly re-evaluate your Query Store hints strategy
131+
### Regularly reevaluate your Query Store hints strategy
127132

128-
Re-evaluate your existing Query Store hints strategy in the following cases:
133+
Reevaluate your existing Query Store hints strategy in the following cases:
129134

130-
- After known large data distribution changes.
131-
- When the resources available to the database change. For example, when the compute size of your Azure SQL Database, SQL Managed Instance, or SQL Server virtual machine changes.
132-
- Where plan fixing has become long-lived. Query Store hints are best used for short-term fixes.
133-
- Unexpected performance regressions.
135+
- After known large data distribution changes.
136+
- When the resources available to the database change. For example, when the compute size of your Azure SQL Database, SQL Managed Instance, or SQL Server virtual machine changes.
137+
- Where plan fixing has become long-lived. Query Store hints are best used for short-term fixes.
138+
- Unexpected performance regressions.
134139

135140
### Broad impact potential
136141

137142
Query Store hints affect all executions of the query, regardless of parameter set, source application, user, or result set. In the case of accidentally performance regression, Query Store hints created with [sys.sp_query_store_set_hints](../system-stored-procedures/sys-sp-query-store-set-hints-transact-sql.md) can be easily removed with [sys.sp_query_store_clear_hints](../system-stored-procedures/sys-sp-query-store-clear-hints-transact-sql.md).
138143

139-
Carefully load test changes for mission critical or sensitive systems before applying Query Store hints in production.
144+
Carefully load test changes for mission critical or sensitive systems before applying Query Store hints in production.
140145

141146
### Forced parameterization and the RECOMPILE hint are not supported
142147

143-
Applying the `RECOMPILE` query hint with Query Store hints is not supported when the database option [PARAMETERIZATION is set to FORCED](../../t-sql/statements/alter-database-transact-sql-set-options.md#parameterization_option-). For more information, see [Guidelines for Using Forced Parameterization](../../relational-databases/query-processing-architecture-guide.md#forced-parameterization).
148+
Applying the `RECOMPILE` query hint with Query Store hints isn't supported when the database option [PARAMETERIZATION is set to FORCED](../../t-sql/statements/alter-database-transact-sql-set-options.md#parameterization_option-). For more information, see [Guidelines for Using Forced Parameterization](../../relational-databases/query-processing-architecture-guide.md#forced-parameterization).
144149

145-
The `RECOMPILE` hint is not compatible with forced parameterization set at the database level. If the database uses forced parameterization, and the `RECOMPILE` hint is part of the hints string set in Query Store for a query, the Database Engine ignores the `RECOMPILE` hint and applies other hints if specified. Additionally, starting in July 2022 in Azure SQL Database, a warning (error code 12461) is issued stating that the `RECOMPILE` hint was ignored.
150+
The `RECOMPILE` hint isn't compatible with forced parameterization set at the database level. If the database uses forced parameterization, and the `RECOMPILE` hint is part of the hints string set in Query Store for a query, the Database Engine ignores the `RECOMPILE` hint and applies other hints if specified. Additionally, starting in July 2022 in Azure SQL Database, a warning (error code 12461) is issued stating that the `RECOMPILE` hint was ignored.
146151

147152
For information on which query hints can be applied, see [Supported query hints](../system-stored-procedures/sys-sp-query-store-set-hints-transact-sql.md#supported-query-hints).
148153

149154
## Related content
150155

151156
- [Save an Execution Plan in XML Format](save-an-execution-plan-in-xml-format.md)
152-
- [Display and Save Execution Plans](display-and-save-execution-plans.md)
157+
- [Display and save execution plans](display-and-save-execution-plans.md)
153158
- [Configure the max degree of parallelism (MAXDOP) in Azure SQL Database](/azure/azure-sql/database/configure-max-degree-of-parallelism)

0 commit comments

Comments
 (0)