En formation, la question revient invariablement : comment ordonner les enregistrements résultant d’un select sur une vue…
La réponse est on ne peut plus simple : avec un ORDER BY !
Bon, OK, un peu d’humour ne fait pas de mal… Mais de quel order by parle t’on ? Du order by dans la déclaration de la vue ?
Prenons une requête de référence, ordonnée comme on le souhaite :
Use AdventureWorks GO SELECT * FROM sales.SalesOrderHeader ORDER BY OrderDate DESC,SalesOrderID ASC;
Reprenons le code de ce select pour créer une vue :
CREATE VIEW vDemoOrderBy AS SELECT * FROM sales.SalesOrderHeader ORDER BY OrderDate DESC,SalesOrderID ASC GO
Oups, cela ne fonctionne pas. Le message est clair : impossible d’utiliser une clause order by dans une vue, a moins d’utiliser un des opérateurs suivants : TOP, OFFSET ou FOR XML.
Les anciens, ayant connu SQL Server 2000, connaissaient l’astuce : ajouter une clause TOP, avec 100 PERCENT en argument et hop, le tour était joué !
CREATE VIEW vDemoOrderBy AS SELECT TOP 100 PERCENT * FROM sales.SalesOrderHeader ORDER BY OrderDate DESC,SalesOrderID ASC GO
Cool, on vient donc de créer une vue, qui a priori renvoie un résultat trié puisque un order by est présent dans le code …
SELECT * FROM sales.SalesOrderHeader ORDER BY OrderDate DESC,SalesOrderID ASC SELECT * FROM vDemoOrderBy
La première requête est notre requête de référence, alors que la seconde fait appel à la vue “triée”. Et le résultat n’est absolument pas identique :
Le comportement de SQL Server a changé depuis SQL Server 2005. Lorsque, dans une vue, les opérateurs ORDER BY et TOP sont combinés, le order by est ignoré !!!
L’affichage du plan d’exécution valide ce point : il n’y a pas de tri lors de l’utilisation de la vue.
Conclusion : ne faites pas confiance au order by contenu dans une vue. Si vous avez réellement besoin d’obtenir un résultat trié en sortie d’une vue, alors ajoutez le order by à la requête qui accède à la vue et chassez le mythe de la vue ordonnée !
Et, souvenez vous bien que le tri est couteux, en terme de ressources système (79% du cout de la requête dans le cas présent). Donc, ne triez le résultat que si vous avez réellement besoin que ce soit le cas. Sinon, abstenez vous, ou bien reportez le tri côté client si possible, et comparez les performances et la montée en charge.
Happy sorting !