264
Chapitre 8. Optimisation du code SQL
après exécution, @i vaut 19973, ce qui est la cardinalité de la table Person.Contact.
Pour des considérations de performances, cela signifie une chose : même si la
requête est écrite en pur SQL, elle peut être plus ou moins efficace selon la stratégie
décidée par l’optimiseur. Certaines constructions SQL permettent des stratégies
optimales, d’autres forcent le plan à utiliser des opérations proches d’un fonctionnement de curseur. C’est notamment le cas de syntaxes introduites dans SQL Server
2005, comme la clause PIVOT et les fonctions de fenêtrage. Leur utilité est donc à
balancer avec leur coût, et elles sont à bannir autant que possible, surtout lorsqu’il
existe une syntaxe plus traditionnelle. Prenons un exemple. Nous voulons obtenir
une liste des contacts avec, pour chaque ligne, le nombre total de personnes portant
le même nom de famille. Nous pouvons utiliser une sous-requête ou une fonction de
fenêtrage :
-- SELECT avec sous-requête
SELECT
t.FirstName,
t.LastName,
(SELECT COUNT(*)
FROM Person.Contact
WHERE LastName = t.LastName) cnt
FROM Person.Contact t
GO
-- SELECT avec fonction de fenêtrage
SELECT
t.FirstName,
t.LastName,
COUNT(*) OVER (PARTITION BY LastName) as cnt
FROM Person.Contact t
GO
Nous voyons le résultat de la trace sur la figure 8.10. La requête utilisant la sousrequête a nécessité environ 1 200 lectures, alors que celle utilisant la fonction de
fenêtrage a lu 47 000 pages, et en a écrit 12. La raison de ces lectures et écriture est
la création d’une table de travail (opérateur table spool). À l’heure actuelle, dans
SQL Server 2005, la première requête est donc bien plus performante.
Figure 8.10 — Différence de performances
Ce choix entre une syntaxe ou une autre n’a pas de valeur absolue, et c’est pour
cette raison que nous disons « à l’heure actuelle ». Comme l’optimiseur SQL évolue,
il est possible que le plan d’exécution de la fonction de partitionnement s’améliore
dans le futur. Il paraît toutefois peu probable qu’il finisse par dépasser en performances la syntaxe utilisant la sous-requête. La règle de base qu’on peut en déduire est
Précédent

- 276/334

Suivant