263
8.3 Optimisation du code SQL
WHERE c.ContactId = e.ContactId
GO
SELECT c.FirstName, c.LastName
FROM Person.Contact c
JOIN HumanResources.Employee e ON c.ContactId = e.ContactId
GO
SELECT c.FirstName, c.LastName
FROM Person.Contact c
WHERE EXISTS (SELECT *
FROM HumanResources.Employee e WHERE c.ContactId = e.ContactId)
GO
SELECT c.FirstName, c.LastName
FROM Person.Contact c
WHERE c.ContactId IN (SELECT e.ContactId
FROM HumanResources.Employee e)
GO
Les deux premiers plans sont identiques, les deux suivants aussi, qui incluent un
tri (distinct sort). Le nombre de reads est identique, et considérant la faible volumétrie (290 lignes retournées), les performances sont, dans les faits, les mêmes, même si
les deux derniers plans sont plus coûteux. Il n’est donc souvent pas utile de choisir
une syntaxe légèrement différente d’une autre pour améliorer les performances. Testez les plans d’exécution, et choisissez la syntaxe la plus intuitive et la plus lisible.
De même, l’ordre d’apparition des colonnes dans le SELECT, des tables dans la
clause FROM et des expressions dans les clauses WHERE et HAVING, n’a pas d’importance.
La requête sera de toute manière décomposée et récrite durant la phase de compilation. Sur certains SGBDR, l’ordre des tables dans la jointure influe sur les performances. Ce n’est pas le cas en SQL Server. Par contre, l’ordre des colonnes dans les
clauses GROUP BY et ORDER BY peut modifier les performances, en influant sur les tris,
opérations coûteuses.
Écriture ensembliste
Nous l’avons dit, le langage SQL est déclaratif. Il est toutefois aussi ensembliste :
toutes les instructions définissent et travaillent sur des ensembles de données, avec
parfois des entorses à l’algèbre relationnelle (la clause ORDER BY par exemple est une
hérésie pour le modèle relationnel, où les tuples d’une relation n’ont aucun ordre
précis. SQL permet de générer un jeu de résultat trié, ce qui viole la théorie relationnelle, mais est très utile). Il est donc important d’éviter le plus possible des syntaxes
non déclaratives et non ensemblistes, le plus triste exemple étant le curseur. Les
boucles WHILE entrent dans ce cas de figure.
Nous avons également dit que, bien que le langage soit ensembliste, l’exécution
est procédurale : le moteur de stockage doit finalement parcourir les lignes ou les clés
d’un index une à une. Ce simple exemple suffit à la démontrer :
DECLARE @i int;
SET @i = 0;
SELECT @i = @i + 1 FROM Person.Contact;
SELECT @i;
8.3 Optimisation du code SQL
WHERE c.ContactId = e.ContactId
GO
SELECT c.FirstName, c.LastName
FROM Person.Contact c
JOIN HumanResources.Employee e ON c.ContactId = e.ContactId
GO
SELECT c.FirstName, c.LastName
FROM Person.Contact c
WHERE EXISTS (SELECT *
FROM HumanResources.Employee e WHERE c.ContactId = e.ContactId)
GO
SELECT c.FirstName, c.LastName
FROM Person.Contact c
WHERE c.ContactId IN (SELECT e.ContactId
FROM HumanResources.Employee e)
GO
Les deux premiers plans sont identiques, les deux suivants aussi, qui incluent un
tri (distinct sort). Le nombre de reads est identique, et considérant la faible volumétrie (290 lignes retournées), les performances sont, dans les faits, les mêmes, même si
les deux derniers plans sont plus coûteux. Il n’est donc souvent pas utile de choisir
une syntaxe légèrement différente d’une autre pour améliorer les performances. Testez les plans d’exécution, et choisissez la syntaxe la plus intuitive et la plus lisible.
De même, l’ordre d’apparition des colonnes dans le SELECT, des tables dans la
clause FROM et des expressions dans les clauses WHERE et HAVING, n’a pas d’importance.
La requête sera de toute manière décomposée et récrite durant la phase de compilation. Sur certains SGBDR, l’ordre des tables dans la jointure influe sur les performances. Ce n’est pas le cas en SQL Server. Par contre, l’ordre des colonnes dans les
clauses GROUP BY et ORDER BY peut modifier les performances, en influant sur les tris,
opérations coûteuses.
Écriture ensembliste
Nous l’avons dit, le langage SQL est déclaratif. Il est toutefois aussi ensembliste :
toutes les instructions définissent et travaillent sur des ensembles de données, avec
parfois des entorses à l’algèbre relationnelle (la clause ORDER BY par exemple est une
hérésie pour le modèle relationnel, où les tuples d’une relation n’ont aucun ordre
précis. SQL permet de générer un jeu de résultat trié, ce qui viole la théorie relationnelle, mais est très utile). Il est donc important d’éviter le plus possible des syntaxes
non déclaratives et non ensemblistes, le plus triste exemple étant le curseur. Les
boucles WHILE entrent dans ce cas de figure.
Nous avons également dit que, bien que le langage soit ensembliste, l’exécution
est procédurale : le moteur de stockage doit finalement parcourir les lignes ou les clés
d’un index une à une. Ce simple exemple suffit à la démontrer :
DECLARE @i int;
SET @i = 0;
SELECT @i = @i + 1 FROM Person.Contact;
SELECT @i;
