# Utiliser sp_whoisactive pour voir les requêtes actives

> Installer sp_WhoIsActive et choisir ses paramètres : plans d'exécution, tête d'une chaîne de blocage, allocations mémoire, durée moyenne.
>
> Source : https://www.pachadata.com/docs/howtos/diagnostic/sp_whoisactive/
> Auteur : Rudi Bruchez · mis à jour le 2026-10-14
> Version Markdown de la page, pour les outils et les LLM. La page HTML fait référence.


[`sp_WhoIsActive`](https://github.com/amachanic/sp_whoisactive/releases) est la procédure stockée d'Adam Machanic qui montre ce qui s'exécute sur une instance à l'instant présent. Pour chaque session active, elle donne le texte de la requête, l'attente en cours, la session qui la bloque, le CPU consommé et les lectures, sous une forme bien plus lisible que `sp_who2`.

## Installation

Le script `sp_WhoIsActive.sql` se télécharge sur le [dépôt GitHub](https://github.com/amachanic/sp_whoisactive). Prenez la version qui correspond à votre instance : le fichier à la racine du dépôt vise SQL Server 2022 et les versions suivantes, celui du dossier `2019` couvre SQL Server 2012 à 2019, celui du dossier `2008` les versions 2005 à 2008.

Le script crée la procédure dans la base de la connexion courante. Installez-la dans `master` : grâce au préfixe `sp_`, vous pourrez l'appeler depuis n'importe quelle base de l'instance.

L'utilisateur qui l'exécute a besoin de la permission `VIEW SERVER STATE`. Certaines options, comme la collecte des verrous, accèdent aussi aux bases concernées pour retrouver le nom des objets. Si l'utilisateur n'y a pas de droits, la procédure affiche le message d'erreur à la place du nom.

## Paramètres utiles

Les paramètres suivants ajoutent des colonnes que la procédure ne collecte pas par défaut.

| Paramètre | Type | Défaut | Effet |
|-----------|------|--------|-------|
| `@get_plans` | `tinyint` | `0` | `1` ajoute la colonne `query_plan` avec le plan de l'instruction en cours ; `2` donne le plan complet du lot ou de la procédure. |
| `@find_block_leaders` | `bit` | `0` | `1` ajoute la colonne `blocked_session_count`, le nombre total de sessions bloquées en aval de chaque session, sur toute la chaîne de blocage. |
| `@get_memory_info` | `bit` | `0` | `1` ajoute les colonnes `requested_memory`, `granted_memory` et `max_used_memory`, ainsi que `memory_info`, un XML qui détaille l'octroi de mémoire, le sémaphore de ressource et les réglages de Resource Governor qui le limitent. |
| `@get_avg_time` | `bit` | `0` | `1` ajoute la colonne `dd hh:mm:ss.mss (avg)`, la durée moyenne des exécutions passées de la requête active, lue dans `sys.dm_exec_query_stats`. |

Le plan renvoyé par `@get_plans` est celui qui est en cours d'exécution. Il ne contient pas les nombres de lignes réels d'un plan d'exécution réel, qui ne sont connus qu'à la fin de la requête. Les plans de grosses requêtes pèsent parfois plusieurs mégaoctets de XML, et c'est la raison pour laquelle la procédure ne les collecte pas par défaut.

Les colonnes de mémoire de `@get_memory_info` sont exprimées en pages de 8 Ko : sur SQL Server 2025, une requête de tri qui avait obtenu 1 024 Ko affichait `128` dans `granted_memory`, et `1024` dans le `granted_memory_kb` du XML `memory_info`. Les sessions sans octroi de mémoire affichent `NULL`.

Vous pouvez combiner les paramètres :

```sql
EXEC sp_WhoIsActive
    @get_plans = 1,
    @get_memory_info = 1;
```

## La tête d'une chaîne de blocage

La colonne `blocking_session_id` ne montre que le bloqueur direct d'une session. Quand une session en bloque une autre, qui en bloque elle-même d'autres, les sessions du bas de la chaîne semblent bloquées par une session qui attend elle aussi. Le problème vient de la session en tête de chaîne, et c'est elle qu'il faut trouver.

`@find_block_leaders = 1` parcourt la chaîne et compte, pour chaque session, toutes les sessions bloquées en aval. Triez sur cette colonne pour voir la tête de chaîne en premier :

```sql
EXEC sp_WhoIsActive
    @find_block_leaders = 1,
    @sort_order = '[blocked_session_count] DESC';
```

Voici le résultat sur SQL Server 2025, avec quatre sessions qui lancent la même mise à jour dans une transaction. La session 79 a modifié les lignes puis garde sa transaction ouverte, la session 78 attend ses verrous, et les sessions 68 et 80 attendent la session 78.

| `session_id` | `blocking_session_id` | `blocked_session_count` | `wait_info` |
|---|---|---|---|
| 79 | `NULL` | 3 | `(7439ms)WAITFOR` |
| 78 | 79 | 2 | `(5389ms)LCK_M_U` |
| 68 | 78 | 0 | `(3435ms)LCK_M_U` |
| 80 | 78 | 0 | `(3331ms)LCK_M_U` |

Les sessions 68 et 80 indiquent 78 comme bloqueur, mais la session 79 bloque trois sessions au total : c'est la tête de la chaîne. Dans cette démonstration, elle exécutait un `WAITFOR`. En production, la tête de chaîne est souvent une session inactive qui a laissé une transaction ouverte. La procédure l'affiche quand même, car `@show_sleeping_spids` vaut `1` par défaut et remonte les sessions inactives qui ont une transaction ouverte.

## L'aide intégrée

La procédure documente elle-même tous ses paramètres et toutes ses colonnes de sortie :

```sql
EXEC sp_WhoIsActive @help = 1;
```

La documentation complète, rédigée par l'auteur, se trouve sur [whoisactive.com](https://whoisactive.com/docs/).


---

## L'auteur

Rudi Bruchez, consultant SQL Server indépendant depuis 2006 : audit de performance, optimisation, migrations, haute disponibilité et formation. Pour un audit ou une intervention sur votre serveur : https://www.pachadata.com/contact/ (audit à distance : https://www.pachadata.com/services/audit-sql-server-a-distance/).
