Aller au contenu principal
{}
Retour à tous les articles

Article technique

Optimiser une requête SQL Server avec les plans

Combinez plans, lectures logiques et essais contrôlés. Un seek ou une suggestion d’index ne suffit pas à prouver une amélioration.

Par Jordy L’Oeuille3 minutes de lecture
  • SQL
  • SQL Server
Base de données SQL Server avec un plan d’exécution ramifié et une comparaison des coûts des requêtes.
Dans cet article

Recueillir des preuves avant d’ajouter un index

Optimiser une requête SQL Server demande plus que rechercher un parcours complet. Consignez requête, types des paramètres, version, niveau de compatibilité, index et distribution des données. Notez si la lenteur est permanente ou liée à certains clients ou moments. Une attente due à un blocage ne s’analyse pas comme un excès de lectures logiques. L’exemple utilise une table temporaire et des commandes fictives. Il illustre une comparaison contrôlée, pas un résultat client mesuré ni une recommandation pour votre schéma de production. Conservez la requête et le plan initiaux.

Plans estimés, plans réels et statistiques

Un plan estimé ne contient pas les mesures d’une requête exécutée. Un plan réel collecte des informations pendant l’exécution : la requête s’exécute donc effectivement. Utilisez une base de test sûre et les droits nécessaires. SET STATISTICS IO affiche notamment les lectures logiques de pages depuis le cache de données ; SET STATISTICS TIME indique les temps CPU et écoulés. Le nombre de résultats n’est pas le nombre de pages lues. Comparez ces informations sur la même requête et les mêmes données, sans assimiler un petit résultat à de faibles entrées-sorties.

Comparer un index candidat sur des données fictivesexamples/sql-server-query-review.sqlsql
-- SQL Server example. Use a NEW session in a separate test database.
-- Never run this in production. Stop on the first error and close the session.
-- Enable Include Actual Execution Plan in your SQL client before running.
CREATE TABLE #cg_sqlserver_orders (
    id int NOT NULL PRIMARY KEY,
    customer_id int NOT NULL,
    created_at datetime2(0) NOT NULL
);
INSERT INTO #cg_sqlserver_orders VALUES
    (1,42,'2026-08-31T23:59:59'), (2,42,'2026-09-01T00:00:00'),
    (3,42,'2026-09-01T12:00:00'), (4,42,'2026-09-01T12:00:00'),
    (5,42,'2026-09-02T00:00:00'), (6,7,'2026-09-01T12:00:00'),
    (7,42,'2026-09-01T23:59:59'), (8,42,'2026-09-02T00:00:01');

DECLARE @customer_id int = 42;
DECLARE @from datetime2(0) = '2026-09-01T00:00:00';
DECLARE @until datetime2(0) = '2026-09-02T00:00:00';
SET STATISTICS IO ON;
SET STATISTICS TIME ON;

SELECT id, customer_id, created_at FROM #cg_sqlserver_orders
WHERE customer_id = @customer_id AND created_at >= @from AND created_at < @until
ORDER BY created_at DESC, id DESC;

CREATE INDEX cg_sqlserver_customer_date_id
ON #cg_sqlserver_orders(customer_id, created_at, id);

SELECT id, customer_id, created_at FROM #cg_sqlserver_orders
WHERE customer_id = @customer_id AND created_at >= @from AND created_at < @until
ORDER BY created_at DESC, id DESC;

SET STATISTICS IO OFF;
SET STATISTICS TIME OFF;
-- Expected IDs in both results: 7, 4, 3, 2. Inspect each SELECT separately.
-- Index creation also produces messages; do not confuse them with SELECT costs.
-- Eight rows cannot establish a production speedup. A scan can be appropriate.

Lire les opérateurs dans leur contexte

Comparez les nombres estimés et réels aux opérateurs pertinents. De grands écarts peuvent justifier une étude des statistiques, paramètres et distributions. Examinez prédicats résiduels, tris, débordements et conversions implicites, mais expliquez leur origine avant toute correction. Un seek suivi de nombreuses recherches peut coûter plus qu’un scan. Une suggestion d’index manquant est une piste, pas une autorisation automatique : elle ne tranche pas les coûts d’écriture ni les chevauchements. Ne modifiez pas simultanément requête, index et serveur si vous voulez comprendre l’effet d’une seule intervention.

Valider plusieurs paramètres et le même résultat

La démonstration attend les ID 7, 4, 3 et 2. Elle couvre un autre client, les deux bornes et des dates égales. Dans une application réelle, testez petits et grands clients, valeurs fréquentes ou rares et résultats vides. Les plans dépendants des paramètres peuvent se comporter différemment. Recompiler ou forcer un plan n’est pas une correction par défaut sans analyse. Vérifiez le résultat métier et les restrictions d’accès, pas seulement le nombre de lignes ou le dessin du plan. Préservez l’isolation requise : NOLOCK peut modifier la correction des résultats et ne remplace pas un diagnostic.

Maîtriser la mise en œuvre

Mesurez plusieurs essais en documentant cache et charge simultanée. Ne videz pas un cache de production pour embellir une comparaison. Contrôlez ensuite insertions, mises à jour et stockage des index. Convenez d’un retour et de critères d’arrêt avant toute modification en production. Cet exemple T-SQL n’a pas été exécuté ici sur SQL Server ; les identifiants attendus décrivent la logique des données, pas un plan ou un temps validé sur ce moteur. Adaptez explicitement version, droits et schéma à l’environnement réel et documentez les risques restant à vérifier.

Poursuivre l’analyse

Un plan de requête ne représente qu’une partie du diagnostic. Les références ci-dessous relient l’analyse technique à un service SQL délimité. Les démonstrations utilisent des données fictives et non les résultats d’une mission client. Pour une demande, commencez par décrire le problème avec un contexte anonymisé, sans mot de passe, dump complet ni données personnelles.

Dernière mise à jour :

Examiner une requête SQL lente

Indiquez version de base, problème et résultat attendu. Partagez uniquement des requêtes ou plans anonymisés après accord sur le besoin.