Utiliser ABORT_QUERY_EXECUTION pour bloquer l’exécution de requêtes dans SQL Server 2025
ABORT_QUERY_EXECUTION est un nouveau “query hint” (SQL Server 2025 / 17.x) conçu comme un frein d’urgence : il permet de bloquer l’exécution future d’une requête identifiée comme problématique (consommation CPU/IO excessive, requête “runaway”, reporting non essentiel qui met en péril un workload critique, etc.).
Si vous l’ajoutez en hint de requête, il déclenche un échec immédiat de la requête.
C’est utile en production, combiné avec un Query Store Hint : vous pouvez ainsi bloquer une requête spécifique (identifiée par son query_id dans le Query Store) sans modifier le code applicatif.
Concrètement
- La requête échoue immédiatement avec l’erreur 8778 (sévérité 16) : « Query execution has been aborted because the ABORT_QUERY_EXECUTION hint was specified. »
- L’objectif principal est l’usage administratif via le Query Store (donc sans modifier le code applicatif).
- Il n’arrête pas une requête déjà en cours : il ne s’applique qu’aux exécutions futures. Pour stopper une exécution en cours, il faut utiliser
KILL. Attention : une exécution interrompue parKILLn’est pas enregistrée dans le Query Store. - Vous ne pouvez pas bloquer une requête “inconnue” : il faut au minimum qu’une exécution de la requête soit enregistrée dans Query Store (même si l’exécution a échoué, expiré ou a été annulée). Si la requête n’y figure pas encore, laissez-la se terminer ou expirer plutôt que de la tuer.
ABORT_QUERY_EXECUTIONest disponible sur Azure SQL Database, Azure SQL Managed Instance (avec la politique de mise à jour Always-up-to-date), et SQL Server 2025 (17.x).- Les Query Store hints ne s’appliquent pas aux requêtes éligibles au paramétrage simple : le hint est enregistré, mais la requête s’exécute. Pour ces requêtes, la colonne
query_parameterization_type_descdesys.query_store_queryvautSimple.
Ce n’est pas un “timeout” paramétrable. C’est une interdiction d’exécuter (par identification Query Store), donc un mécanisme de gouvernance/production.
Activer le hint dans le Query Store
Le Query Store doit être activé.
Il faut identifier le query_id de la requête à bloquer, puis appliquer le hint ABORT_QUERY_EXECUTION via la procédure stockée sys.sp_query_store_set_hints.
Identifier le query_id à bloquer
Vous pouvez :
- passer par les rapports Query Store dans SSMS,
- ou interroger les vues de catalogue.
Les hints sont gérés avec :
sys.sp_query_store_set_hints(création/mise à jour)sys.sp_query_store_clear_hints(suppression)- La visibilité/diagnostic passe par la vue catalogue
sys.query_store_query_hints.
Il faut une permission ALTER sur la base pour définir/retirer ces hints.
Attribuer le Query Hint
Dans les exemples suivants, 39 est le query_id de la requête à bloquer : remplacez-le par celui que vous avez trouvé.
EXEC sys.sp_query_store_set_hints
@query_id = 39,
@query_hints = N'OPTION (USE HINT (''ABORT_QUERY_EXECUTION''))';
Toute exécution future de la requête attachée à query_id = 39 échoue avec l’erreur 8778.
Avec l’optimisation des plans sensibles aux paramètres (PSP, niveau de compatibilité 160 et plus), une même requête paramétrée peut avoir un query_id parent et des variantes, qui ont chacune leur propre query_id. Les statistiques d’exécution sont enregistrées sous les variantes. Un hint posé sur le parent est hérité par les variantes. Posé sur une variante, il ne bloque que les exécutions routées vers cette variante. Vérifiez dans sys.query_store_query_variant (colonne parent_query_id) que vous bloquez bien le parent.
Vérifier que la requête est bien “bloquée”
La vue sys.query_store_query_hints expose le texte du hint, sa source et la raison du dernier échec d’application éventuel (si un hint n’a pas pu s’appliquer).
SELECT query_hint_id,
query_id,
replica_group_id,
query_hint_text,
last_query_hint_failure_reason,
last_query_hint_failure_reason_desc,
query_hint_failure_count,
source,
source_desc
FROM sys.query_store_query_hints
WHERE query_id = 39;
Débloquer (revenir en arrière)
Vous pouvez supprimer tous les hints pour le query_id :
EXEC sys.sp_query_store_clear_hints @query_id = 39;
Si vous aviez plusieurs hints et souhaitez garder les autres, réappliquez sp_query_store_set_hints en retirant seulement ABORT_QUERY_EXECUTION.
Inventorier tous les blocages
Pour lister toutes les requêtes bloquées via ABORT_QUERY_EXECUTION :
SELECT qh.query_id,
qh.query_hint_text,
qh.query_hint_failure_count,
qh.last_query_hint_failure_reason_desc,
qt.query_sql_text
FROM sys.query_store_query_hints AS qh
JOIN sys.query_store_query AS q
ON q.query_id = qh.query_id
JOIN sys.query_store_query_text AS qt
ON qt.query_text_id = q.query_text_id
WHERE qh.query_hint_text LIKE N'%ABORT_QUERY_EXECUTION%'
ORDER BY qh.query_id DESC;
Si le hint est présent, mais ne s’applique pas
Utilisez sys.query_store_query_hints et regardez :
last_query_hint_failure_reason_descquery_hint_failure_count
Ces colonnes ne révèlent pas le cas du paramétrage simple : le hint est ignoré, et la raison d’échec reste à NONE. Vérifiez alors query_parameterization_type_desc dans sys.query_store_query.
Readable secondaries
SQL Server 2025 rend disponible, encore en préversion, le Query Store sur les réplicas secondaires lisibles d’un groupe de disponibilité. Une fois cette fonctionnalité activée pour la base, sys.sp_query_store_set_hints expose un paramètre @replica_group_id pour contrôler l’étendue d’application du hint selon le groupe de réplicas.
- Vous pouvez vouloir bloquer une requête uniquement sur un secondaire lisible (reporting) sans impacter le primaire, ou l’inverse selon l’architecture.
- Cela devient un levier de gouvernance plus précis quand les workloads sont séparés (lecture/reporting vs OLTP).