Meta tags:
description= Pourquoi les fonctions dans vos clauses WHERE empêchent SQL Server d utiliser vos index, et comment réécrire vos requêtes pour retrouver des performances optimales.;
Headings (most frequently used words):
les, ne, pas, vos, index, sargabilité, et, le, code, qui, categories, cassez, anti, patterns, dans, clauses, where, fait, mal, qu, est, ce, que, la, fonctions, cassent, cas, classiques, comment, corriger, quand, on, peut, modifier, stratégies, optimisation, résumé, exemple, du, coalesce, conversions, implicites, tag, cloud, tags,
Text of the page (most frequently used words):
les (55), sql (40), where (37), est (29), server (28), index (26), dans (25), col (21), pas (18), des (18), null (18), pour (17), sur (17), une (16), colonne (15), #coalesce (14), vous (13), données (12), vos (11), que (11), colonnes (11), qui (11), est_archive (11), sargabilité (11), plus (10), name (9), isnull (9), peut (9), fonction (8), dbo (8), table (8), fonctions (8), sont (7), trim (7), not (7), conversions (7), implicites (7), requête (7), par (7), code (7), 2025 (7), sargable (7), avec (6), select (6), quand (6), quotename (6), cette (6), scan (6), rtrim (6), ltrim (6), requêtes (6), performances (6), from (5), case (5), seek (5), libelle (5), cas (5), anti (5), utiliser (5), upper (5), abc (5), performance (5), lecture (4), nettoyer (4), insertion (4), jamais (4), set (4), left (4), and (4), when (4), produit (4), alter (4), être (4), optimiseur (4), exemple (4), côté (4), base (4), patterns (4), clauses (4), non (4), prédicat (4), casse (4), lower (4), toutes (4), dictionnaire (4), administration (4), transactions (4), rudi (3), bruchez (3), votre (3), expertise (3), avez (3), solution (3), default (3), types (3), déplacer (3), logique (3), paramètre (3), valeur (3), voici (3), order (3), type (3), sys (3), contiennent (3), avant (3), marque (3), correspondance (3), cet (3), calculée (3), quelques (3), problèmes (3), calculées (3), expression (3), fait (3), automatiquement (3), problème (3), autre (3), collation (3), clause (3), classiques (3), comment (3), datecol (3), year (3), convert (3), pages (3), pourquoi (3), docs (3), maintenance (3), transaction (3), alwayson (3), diagnostic (3), journaux (3), tous (2), 2026 (2), besoin (2), propres (2), doivent (2), éviter (2), stratégies (2), optimisation (2), résumé (2), nb_null (2), filtrer (2), sans (2), union (2), all (2), schema_id (2), join (2), tables (2), object_id (2), columns (2), then (2), else (2), end (2), nullable (2), réalité (2), plan (2), exécution (2), add (2), ajouter (2), contraintes (2), test (2), pouvez (2), modélisation (2), article (2), blog (2), entre (2), doit (2), correspondra (2), mais (2), est_archive_safe (2), ajout (2), accès (2), modifier (2), autres (2), production (2), convertit (2), comparaison (2), comme (2), car (2), sera (2), même (2), différence (2), tout (2), simple (2), évaluer (2), chaque (2), ligne (2), empêche (2), rien (2), défaut (2), instances (2), appliquer (2), faire (2), comparaisons (2), souvent (2), inutile (2), espaces (2), chaînes (2), utilisation (2), recherches (2), corriger (2), réécrire (2), date (2), réécriture (2), fréquents (2), cassent (2), recherche (2), lettre (2), cherchez (2), parcourir (2), parcours (2), complet (2), stockées (2), mot (2), résultat (2), mal (2), categories (2), cassez (2), articles (2), shrink (2), mémoire (2), journal (2), installation (2), architecture (2), ressources (2), serveur (2), optimiser (2), compteurs (2), analyser (2), auto (2), sauvegardes (2), always (2), tempdb (2), français (2), droits, réservés, services, contactez, moi, parlons, projet, possible, propre, modéliser, paramètres, correspondre, vérifier, checklist, développeur, sp_executesql, exec, garder, len, retirer, dernier, is_nullable, schemas, sum, count, nb_lignes, nvarchar, max, declare, trouver, script, identifier, aucun, candidates, idéales, passage, désormais, alors, était, df_marque_est_archive, for, constraint, bit, column, update, existants, agit, rendre, éventuellement, contrainte, élimine, fragile, incertaine, informations, voyez, paul, white, properly, persisted, computed, options, connexion, fonctionne, ansi_nulls, quoted_identifier, différentes, exacte, cela, pose, pratiques, include, ix_produit_computed, create, création, créer, reproduit, exactement, utilisée, puis, indexer, lien, théoriquement, classique, chez, éditeurs, logiciel, source, éditeur, corrigera, futur, proche, reste, deux, solutions, voir, sujet, post, bob, ward, depuis, 2022, extended, event, détecte, pensez, configurer, environnements, détecter, mise, query_antipattern, abordé, aspect, toujours, hiérarchie, convertie, perdu, moindre, précédence, fréquent, perte, correspond, côtés, subtilité, définie, éliminer, appel, compilation, sait, revanche, simplifié, façon, comportement, documentée, intéressant, savoir, pratique, préférable, risque, erik, darling, défaire, extraire, pouvoir, définition, voit, interne, traduit, écrivez, presque, veut, dire, sais, général, utilisées, mauvais, escient, habitudes, héritées, moteurs, sensibles, oracle, postgresql, plupart, installées, insensible, donc, nécessaire, insensibles, lui, aussi, début, bonne, sert, ignore, fin, sinon, serait, cauchemar, char, effectuer, trimées, tenir, compte, inline, fn_check, scalaire, udf, insensitive, day, month, like, substring, cast, pattern, leur, milliers, lignes, sembler, faible, lente, fur, mesure, volume, augmentera, flowchart, oui, ciblée, complète, optimale, dégradée, appliquez, transformez, première, mots, dex, quelque, part, devez, valeurs, tester, jusqu, dernière, ouvrez, allez, directement, analogie, chercher, vient, earch, ument, able, résoudre, utilisant, arg, appelle, tombe, régulièrement, genre, audit, généré, orm, écrit, main, emballe, choix, intégralité, est_visible, regardez, coupables, appliqués, filtrées, parle, lieu, direct, minutes, lire, tags, empêchent, retrouver, optimales, tuning, wsfc, windows, log, supervision, sauvegarde, restauration, parallelisme, maxdop, dba, configuration, backup, tag, cloud, page, entreprise, reference, procédures, verrous, statistiques, cardinalité, indexation, événements, étendus, modèle, matériel, règles, introduction, livre, téléchargements, liens, utiles, réplication, parallélisme, rcsi, query, store, execution, cardinality, estimator, bloquer, blocages, clustered, gérer, plusieurs, incréments, kvm, docker, linux, standard, comprendre, basic, availability, groups, bag, maîtriser, timeouts, dbatools, hadr, tracer, plans, sp_whoisactive, erreur, deadlock, allocations, dev, fichiers, bases, systèmes, mongodb, analytique, bcp, taille, prtg, monitoring, errorlog, backups, compression, howtos, iqp, expressions, rationnelles, consomme, toute, ram, normal, dark, light, english, contact, formations,
Text of the page (random words):
ne cassez pas vos index sargabilité et anti patterns dans les clauses where rudi bruchez rudi bruchez expertise formations contact docs blog français fr english français light dark auto docs articles sql server administration installation sql server 2025 pourquoi sql server consomme toute la ram de votre serveur et pourquoi c est normal expressions rationnelles iqp performances sargabilité howtos administration compression errorlog backups monitoring compteurs de base always on ag prtg taille des tables bcp journal de transaction instances analytique mongodb bi bases systèmes déplacer tempdb fichiers tempdb dev collation diagnostic allocations mémoire analyser les requêtes deadlock journaux d erreur sp_whoisactive tracer les plans transaction hadr dbatools alwayson diagnostic alwayson ag always on maîtriser les timeouts sql server standard comprendre les basic availability groups bag linux docker kvm maintenance shrink problèmes de journaux de transactions sauvegardes sur un ag sauvegardes de journaux de transactions modélisation gérer plusieurs auto incréments index clustered performances blocages bloquer l exécution de requêtes cardinality estimator conversions implicites diagnostic execution plan query store rcsi requêtes parallélisme réplication ajout de colonnes ressources liens utiles téléchargements livre optimiser sql server 00 introduction 01 règles de base 02 architecture 03 matériel 04 modèle de données 05 analyser les performances 05 2 compteurs de performances 05 3 événements étendus 06 indexation 06 statistiques et cardinalité 07 transactions et verrous 08 optimiser le code sql 09 procédures stockées 10 ressources du serveur reference sql server entreprise sur cette page le code qui fait mal qu est ce que la sargabilité les fonctions qui cassent vos index les cas classiques et comment les corriger exemple du coalesce conversions implicites quand on ne peut pas modifier le code stratégies d optimisation résumé tag cloud administration 3 alwayson ag 3 architecture 1 backup 1 configuration 1 dba 4 index 1 installation 1 journal de transactions 1 maintenance 2 maxdop 1 mémoire 1 parallelisme 1 performance 3 restauration 1 sargabilité 1 sauvegarde 1 shrink 1 sql server 12 sql server 2025 1 supervision 3 t sql 1 transaction log 1 windows server 1 wsfc 1 categories administration sql server 7 base de données 1 expertise 2 maintenance 1 performance tuning 1 sql server 5 docs articles sql server performances sargabilité ne cassez pas vos index sargabilité et anti patterns dans les clauses where pourquoi les fonctions dans vos clauses where empêchent sql server d utiliser vos index et comment réécrire vos requêtes pour retrouver des performances optimales tags sql server performance t sql index sargabilité categories sql server 8 minutes à lire tl dr appliquer une fonction sur une colonne dans la clause where empêche sql server d utiliser les index sur cette colonne on parle de requête non sargable le résultat un index scan parcours complet au lieu d un index seek accès direct les coupables les plus fréquents coalesce isnull convert year left trim appliqués sur les colonnes filtrées la solution déplacer la logique du côté de la valeur ou du paramètre jamais du côté de la colonne le code qui fait mal regardez cette requête select libelle from dbo produit where coalesce est_archive and coalesce est_visible je tombe régulièrement sur ce genre de code en audit ça peut être généré par un orm ou écrit à la main le résultat est une requête qui ne peut pas utiliser les index coalesce emballe les colonnes du where dans une fonction et sql server n a plus d autre choix que de parcourir l intégralité de la table pour évaluer chaque ligne c est ce qu on appelle un problème de sargabilité qu est ce que la sargabilité sargable vient de s earch arg ument able un prédicat sargable est un prédicat que l optimiseur de requêtes peut résoudre en utilisant un index l analogie la plus simple chercher un mot dans un dictionnaire si vous cherchez le mot index vous ouvrez le dictionnaire à la lettre i et vous y allez directement c est un index seek si vous cherchez tous les mots qui contiennent dex quelque part vous devez parcourir toutes les pages du dictionnaire c est un index scan ou un table scan le parcours complet de toutes les valeurs stockées pour toutes les tester jusqu à la dernière quand vous appliquez une fonction sur une colonne dans le where vous transformez votre recherche par la première lettre en recherche dans tout le dictionnaire flowchart td a requête avec where b prédicat sargable b oui c index seek b non d index scan c e lecture ciblée quelques pages d f lecture complète toutes les pages de l index e g performance optimale f h performance dégradée sur une table de quelques milliers de lignes la différence peut sembler faible en production la requête sera de plus en plus lente au fur et à mesure que le volume de table augmentera les fonctions qui cassent vos index voici les anti patterns les plus fréquents avec leur réécriture sargable anti pattern exemple non sargable réécriture sargable coalesce dans le where where coalesce col x where col x or col is null isnull dans le where where isnull col 0 1 where col 1 si not null ou where col 1 or col is null trim ltrim rtrim where ltrim rtrim col abc where col abc nettoyer les données à l insertion convert cast sur une date where convert date col 2025 01 01 where col 2025 01 01 and col 2025 01 02 left substring where left col 3 abc where col like abc year month day where year datecol 2025 where datecol 2025 01 01 and datecol 2026 01 01 upper lower where upper col abc utiliser une collation case insensitive ci fonction scalaire udf where dbo fn_check col 1 réécrire la logique en inline les cas classiques et comment les corriger un des cas les plus classiques d utilisation de fonctions dans la clause where c est l utilisation des fonctions trim ltrim ou rtrim ou lower ou upper pour effectuer des recherches avec des chaînes qui sont trimées ou faire des recherches sans tenir compte de la casse le trim dans la clause where est souvent inutile le rtrim ne sert à rien car sql server ignore les espaces de fin dans les comparaisons de chaînes sinon la comparaison sur des types de données char serait un cauchemar le ltrim est lui aussi souvent inutile si vous avez des espaces de début dans vos données c est que les données ne sont pas propres à l insertion la bonne solution est de nettoyer les données à l insertion pas à la lecture les fonctions upper et lower sont en général utilisées à mauvais escient ce sont des habitudes héritées de moteurs sensibles à la casse par défaut comme oracle ou postgresql en sql server la plupart des instances sont installées avec une collation par défaut insensible à la casse ci donc il n est pas nécessaire d appliquer upper ou lower pour faire des comparaisons insensibles à la casse exemple du coalesce la fonction coalesce empêche le seek presque plus que les autres fonctions ça ne veut rien dire je sais coalesce est en interne traduit par sql server en expression case when quand vous écrivez where coalesce est_archive 0 0 sql server voit en réalité where case when est_archive is not null then est_archive else 0 end 0 l optimiseur ne peut pas défaire cette expression pour en extraire un prédicat simple sur la colonne il doit évaluer le case when pour chaque ligne de la table avant de pouvoir filtrer c est la définition même d un index scan isnull vs coalesce il y a une subtilité si la colonne est définie comme not null sql server peut éliminer l appel à isnull à la compilation car il sait que la valeur ne sera jamais null coalesce en revanche n est pas simplifié de la même façon c est une différence de comportement documentée par erik darling intéressant à savoir mais dans la pratique il est préférable de n utiliser ni l un ni l autre dans les clauses where pour éviter tout risque de non sargabilité conversions implicites un autre cas fréquent de perte de sargabilité les conversions implicites quand le type de données du paramètre ne correspond pas au type de la colonne sql server convertit automatiquement un des côtés de la comparaison le problème sql server convertit toujours le côté de moindre précédence dans la hiérarchie des types si c est la colonne qui est convertie l index est perdu j ai abordé cet aspect dans cet article sur les conversions implicites depuis sql server 2022 l extended event query_antipattern détecte automatiquement les conversions implicites et d autres anti patterns dans les requêtes pensez à le configurer sur vos environnements de test pour détecter les problèmes avant la mise en production voir le post de bob ward sur le sujet quand on ne peut pas modifier le code c est le cas classique chez les éditeurs de logiciel vous n avez pas accès au code source et l éditeur ne corrigera pas le problème dans un futur proche il reste deux solutions côté base de données 1 colonnes calculées index vous pouvez créer une colonne calculée qui reproduit exactement l expression utilisée dans le where puis indexer cette colonne théoriquement sql server fait automatiquement le lien entre la fonction dans la requête et la colonne calculée par exemple ajout des colonnes calculées alter table dbo produit add est_archive_safe as isnull est_archive 0 création de l index sur les colonnes calculées create index ix_produit_computed on dbo produit est_archive_safe include libelle go mais cela pose quelques problèmes pratiques la correspondance entre la fonction dans le where et la colonne calculée doit être exacte isnull col 0 ne correspondra pas à coalesce col 0 ce sont des fonctions différentes pour l optimiseur ltrim rtrim col ne correspondra pas à rtrim ltrim col ni à trim col les options set de la connexion quoted_identifier et ansi_nulls doivent être à on pour que la correspondance fonctionne la correspondance est fragile et incertaine pour plus d informations voyez cet article de blog de paul white properly persisted computed columns 2 contraintes et modélisation s il s agit d un test de null vous pouvez rendre les colonnes not null et éventuellement ajouter une contrainte default si est_archive ne peut pas être null l optimiseur élimine le isnull nettoyer les null existants update dbo marque set est_archive 0 where est_archive is null ajouter les contraintes alter table dbo marque alter column est_archive bit not null alter table dbo marque add constraint df_marque_est_archive default 0 for est_archive go select trim libelle as libelle from dbo produit where isnull est_archive 0 0 order by libelle go le plan d exécution de cette requête est désormais un index seek alors qu avant c était un index scan voici un script pour identifier les colonnes nullable qui ne contiennent en réalité aucun null candidates idéales pour un passage en not null trouver les colonnes nullable qui ne contiennent jamais de null declare sql nvarchar max n select sql sql select quotename s name quotename t name quotename c name as colonne count as nb_lignes sum case when quotename c name is null then 1 else 0 end as nb_null from quotename s name quotename t name union all from sys columns as c join sys tables as t on c object_id t object_id join sys schemas as s on t schema_id s schema_id where c is_nullable 1 and t type u order by s name t name c name retirer le dernier union all set sql left sql len sql 10 filtrer pour ne garder que les colonnes sans null set sql n select from sql n as x where nb_null 0 order by colonne exec sp_executesql sql stratégies d optimisation résumé voici une checklist pour le développeur t sql jamais de fonction sur une colonne dans le where déplacer la logique sur le paramètre ou la valeur vérifier les types de données les paramètres et les colonnes doivent correspondre pour éviter les conversions implicites modéliser avec des not null et des default quand c est possible c est la solution la plus propre nettoyer les données à l insertion pas à la lecture si vous avez besoin de trim dans vos select c est que vos données ne sont pas propres expertise sql server besoin de services avec sql server contactez moi et parlons de votre projet 2026 rudi bruchez tous droits réservés
|