Le point de départ

Là où les DMV répondent à « qu’est-ce qui tourne maintenant », queryinsights répond à « qu’est-ce qui s’est passé ». C’est un schéma de vues auto-générées, présent dans chaque Warehouse et chaque SQL analytics endpoint, qui conserve l’historique des requêtes terminées et quelques agrégats prêts à l’emploi.

Cet article couvre l’historique. Le temps réel (les DMV sys.dm_exec_*, le modèle de concurrence) fait l’objet d’un article séparé.

Règle suivie ici : chaque affirmation est vérifiée en lab avant d’être écrite. Les captures proviennent d’un warehouse de test (lh_dp700_sandbox) chargé avec le jeu de données d’exemple de Fabric, en charge faible. Certaines observations (une vue vide, is_pool_under_pressure toujours à 0) sont des artefacts de ce contexte mono-utilisateur, pas des limites de la plateforme.

Après cette lecture, on saura :

  • choisir la bonne vue queryinsights pour un besoin donné ;
  • lire l’agrégation par forme de requête (query_hash) sans se tromper sur ce qu’elle mesure ;
  • éviter les pièges de nommage entre DMV et queryinsights (login_time vs session_start_time, etc.) ;
  • savoir ce que contient réellement sql_pool_name, et combien de temps l’historique est conservé.

Prérequis : un Fabric Warehouse (ou SQL analytics endpoint) avec un rôle Contributor ou supérieur, et l’éditeur SQL du portail ou un client T-SQL.

1. Les six vues queryinsights

queryinsights regroupe six vues. Chacune répond à un besoin distinct :

VueGrainSert à
exec_requests_historyUne ligne par exécutionRetrouver une requête précise, son texte, sa durée
exec_sessions_historyUne ligne par session terminéeReconstituer qui était connecté et quand
long_running_queriesAgrégat par query_hashRepérer les requêtes récurrentes les plus lentes (médiane)
frequently_run_queriesAgrégat par query_hashRepérer les requêtes les plus fréquentes
sql_pool_insightsJournalisation événementielleSuivre la pression sur le pool de calcul
external_api_call_statsUne ligne par fonction externe appeléeDiagnostiquer les requêtes qui appellent des API externes via les fonctions IA

On les trouve dans l’Explorer du warehouse, sous Schemas > queryinsights > Views. Elles n’existent que dans un Warehouse ou un SQL analytics endpoint.

Rétention : 30 jours. D’après la documentation Microsoft, Query Insights conserve 30 jours d’historique et d’agrégats. Ce point conditionne directement la profondeur d’analyse possible ; il n’a pas été mesuré en lab.

Délai d’apparition : jusqu’à 15 minutes. Une requête terminée n’apparaît pas immédiatement dans queryinsights, et le délai croît avec la concurrence. Si une requête de test ne retourne rien, réessayer quelques minutes plus tard avant de conclure.

Les quatre vues détaillées ci-dessous sont testées en lab. frequently_run_queries et external_api_call_stats ne l’ont pas été : la première suit la même logique d’agrégation par query_hash que long_running_queries, triée par fréquence plutôt que par durée ; la seconde ne concerne que les requêtes utilisant des fonctions IA.

2. exec_requests_history : l’historique détaillé

D’abord, la preuve que la colonne command contient bien, ici, le texte complet de la requête (contrairement à la DMV sys.dm_exec_requests, où command n’est qu’un type d’instruction) :

queryinsights.exec_requests_history sur les 60 dernières minutes, colonne command montrant le texte SQL complet Sur une fenêtre de 60 minutes, command affiche le SQL réel : SELECT session_id, login_name, ..., SET LOCK_TIMEOUT 5000;, DECLARE @IncludeDefinition BIT = 0;. On y voit aussi les requêtes système émises par l’éditeur du portail lui-même.

Requête typique : top 10 des plus lentes sur sept jours, hors bruit interne.

SELECT TOP 10
    login_name, command, start_time, total_elapsed_time_ms
FROM queryinsights.exec_requests_history
WHERE start_time >= DATEADD(DAY, -7, GETUTCDATE())
  AND command <> 'TASK MANAGER'
ORDER BY total_elapsed_time_ms DESC;

Résultat filtré du top 10 des requêtes les plus lentes Le filtre command <> 'TASK MANAGER' fonctionne, mais révèle autre chose : command contient aussi des instructions PRINT (PRINT "Trip batch 10/10 completed (1000 records)") issues du script de chargement du jeu d’exemple, découpé en lots de 1000 lignes.

Piège de nommage : en DMV, la durée s’appelle total_elapsed_time. Ici, total_elapsed_time_ms. Même notion, nom différent selon la couche.

3. exec_sessions_history : l’historique des sessions

SELECT TOP 10
    session_id, login_name, session_start_time, session_end_time
FROM queryinsights.exec_sessions_history
ORDER BY session_start_time DESC;

Piège de nommage : en DMV (sys.dm_exec_sessions), la date de début s’appelle login_time. Ici, session_start_time, accompagnée de session_end_time. Une session encore active y apparaît avec session_end_time = 1900-01-01.

En lab, cette requête s’exécute sans erreur mais renvoie 0 ligne :

queryinsights.exec_sessions_history retourne zéro ligne Résultat vide alors que des sessions ont clairement existé pendant le lab.

La documentation apporte deux éléments qui vont dans le sens d’une explication : la vue est décrite comme couvrant les sessions terminées, et l’apparition dans queryinsights peut prendre jusqu’à 15 minutes. Le lab n’a pas rejoué le test pour trancher lequel des deux jouait ici : soit les sessions étaient encore ouvertes, soit la propagation n’avait pas eu lieu. À revérifier avec un test dédié.

4. long_running_queries : l’agrégation par similarité

SELECT TOP 10
    query_hash, median_total_elapsed_time_ms, number_of_runs
FROM queryinsights.long_running_queries
ORDER BY median_total_elapsed_time_ms DESC;

long_running_queries : agrégation par query_hash La première ligne affiche number_of_runs = 10 et une médiane de 28 464,5 ms : le moteur a regroupé dix exécutions d’une même requête sous un seul query_hash et calculé une durée médiane, au lieu de dix lignes séparées. Les autres lignes sont à number_of_runs = 1, cohérent avec des requêtes de test lancées une seule fois.

L’agrégation se fait sur la forme de la requête : deux requêtes qui ne diffèrent que par leurs littéraux (les valeurs d’un WHERE, par exemple) partagent le même query_hash.

À retenir : long_running_queries répond à “quelle forme de requête coûte cher de façon répétée”, pas “quelle exécution individuelle a été lente”. Pour cette dernière, c’est exec_requests_history.

5. sql_pool_insights : la santé du pool

SELECT TOP 10
    sql_pool_name, timestamp, is_pool_under_pressure
FROM queryinsights.sql_pool_insights
WHERE timestamp >= DATEADD(HOUR, -24, GETUTCDATE())
ORDER BY timestamp DESC;

sql_pool_insights : contenu inattendu de sql_pool_name Surprise : sql_pool_name ne contient pas un nom de ressource mais SELECT ou NONSELECT. Fabric Warehouse isole les ressources entre deux pools par défaut, l’un pour les SELECT, l’autre pour le reste (INSERT, UPDATE, DELETE), et c’est cette catégorie qui apparaît ici. Les lignes arrivent par paires SELECT / NONSELECT à des horodatages espacés d’environ une minute (20:19:16, 20:18:16, 20:17:16), ce qui correspond à une journalisation événementielle : la vue enregistre un événement quand la configuration du pool, la capacité du workspace ou l’état de pression change, les changements de pression étant retenus au pas minimal d’une minute, et uniquement quand le warehouse est actif. is_pool_under_pressure reste à 0, cohérent avec la faible charge du lab.

À retenir : ne pas supposer qu’un nom de colonne fait ce que son nom suggère. Ici, sql_pool_name répond à “quelle catégorie de charge”, pas “quel pool physique”. Vérifier le contenu réel avant de bâtir une alerte dessus.

6. frequently_run_queries : non testée ici

Même structure d’agrégat que long_running_queries (query_hash, number_of_runs), orientée fréquence. Utile pour identifier les requêtes candidates à une optimisation, un cache ou une vue matérialisée. À documenter avec un test dédié.

7. external_api_call_stats : non testée ici

Diagnostics au niveau fonction pour les requêtes qui appellent des API externes via les fonctions IA de Fabric : une ligne par fonction externe distincte utilisée par une requête. Hors périmètre de ce lab.

8. RBAC : le texte des requêtes n’est pas visible par tous

Le texte complet des requêtes dans queryinsights n’est visible que pour les rôles Admin, Member et Contributor. Un Viewer accède aux vues mais pas au texte des commandes.

L’écran Data Warehouse Monitor du portail (ex-« Query Activity »), qui présente les mêmes informations sans écrire de T-SQL, est quant à lui réservé aux Admins. Détail traité dans l’article sur les DMV.

Enfin, la colonne T-SQL derrière le libellé « Submitter » du portail est login_name, dans exec_requests_history comme dans les DMV.

9. Ce qui reste ouvert

Points testés mais pas tranchés avec certitude :

  • pourquoi queryinsights.exec_sessions_history renvoie 0 ligne alors que des sessions ont existé : sessions encore ouvertes, ou propagation non terminée ?
  • le comportement de frequently_run_queries sous charge réelle ;
  • la rétention effective sur un tenant donné (la doc annonce 30 jours).

Chacun mérite un test dédié avant d’en faire une affirmation.

Récapitulatif anti-pièges

PiègeCe qu’il faut retenir
Nombre de vuesSix : les cinq usuelles + external_api_call_stats (fonctions IA)
command (queryinsights)Texte complet, peut inclure des PRINT internes
total_elapsed_time vs total_elapsed_time_msMême notion, nom différent DMV / queryinsights
login_time vs session_start_timeMême notion, nom différent DMV / queryinsights
exec_sessions_historySessions terminées uniquement ; délai jusqu’à 15 min
sql_pool_nameCatégorie de charge (SELECT / NON SELECT), pas un identifiant de pool
long_running_queries / frequently_run_queriesAgrégats par forme de requête (query_hash), pas par exécution
Rétention30 jours d’après la documentation
Texte complet des requêtesVisible pour Admin / Member / Contributor seulement
Data Warehouse Monitor (portail)Réservé aux Admins

Pourquoi ça compte au-delà de l’examen

Pour l’examen DP-700 (domaine “Monitor and optimize an analytics solution”), savoir quelle vue répond à quelle question évite les réponses approximatives.

En production, l’enjeu est de construire un monitoring qui tient : ne pas bâtir une alerte sur sql_pool_name en croyant y lire un nom de ressource, ne pas attendre d’une vue d’agrégats le détail d’une exécution, et savoir que l’historique s’arrête à 30 jours. Mieux vaut le cadrer avant l’architecture que pendant l’incident.

En résumé

queryinsights est l’outil d’analyse historique de Fabric Warehouse :

  • six vues, dont deux d’agrégats par forme de requête (query_hash) et une, external_api_call_stats, souvent oubliée ;
  • des noms de colonnes qui glissent depuis les DMV (login_time / session_start_time, total_elapsed_time / total_elapsed_time_ms) ;
  • sql_pool_name qui porte une catégorie de charge (SELECT / NON SELECT), pas un identifiant de pool ;
  • 30 jours de rétention, et jusqu’à 15 minutes de délai avant qu’une requête n’y apparaisse.

Pour le temps réel et le modèle de concurrence, voir Les DMV de Fabric Warehouse.

Sources officielles