Pourquoi la clause ORDER BY… est-elle interdite au sein d’une requête ?

Certains développeurs pensent naïvement pouvoir mettre une clause de tri ORDER BY un peu partout dans une requête. Il n’est est rien. Une clause ORDER BY ne peut figurer que comme dernière lignes d’une requête de type SELECT. Même si vous pouvez parfois l’écrire à l’intérieur de certaines requêtes (certains SGBDR ne râlant même pas sur cette inadmissible faute) elle sera au mieux ignorée et au pire peut donner des résultats incohérent… Mais pourquoi ?

L’acronyme SGBDR veut dire « Système de Gestion de Base de Données Relationnelles ». Mais c’est quoi le relationnel ?

La théorie de l’Algèbre Relationnelle a été bâtie sur la théorie des ensembles qui ne possède aucune relation d’ordre de manière naturelle.
Il n’existe pas non plus d’ordre naturel dans les lignes des tables dont le contenu doit être considéré comme étant un sac…
Par conséquent, la clause ORDER BY de SQL ne fait d’ailleurs pas partie de l’algèbre relationnelle.

C’est pourquoi les SGBDR l’ignorent en général, ou bien signalent l’erreur, lorsqu’elle figure à l’intérieur des requêtes.

En fait il s’agit d’une clause COSMÉTIQUE c’est à dire appliqué au rendu du résultat et c’est pourquoi elle ne doit figurer qu’une seule fois et à la toute fin de la requête.
On a jugé plus pratique de rajouter cette clause au langage, parce qu’il est généralement moins couteux de demander au SGBDR de trier les données que de le faire sur le poste client. En effet, au niveau physique, il est parfois possible d’éviter le coût du traitement du tri par le simple fait de l’existence d’un index adéquat, puisqu’un index est généralement une forme de tri…

Si vous regardez comment est conçu l’intérieur d’un SGBDR, vous remarquerez que la partie qui assure le tri n’est pas du tout située dans le moteur relationnel. En effet les requêtes relèvent de l’algèbre relationnelle, donc du moteur relationnel, c’est à dire de la partie LOGIQUE du SGBDR. En revanche le tri est une opération physique (le résultat d’une requête est le même que les données soient triées ou non) et relève donc du moteur de stockage !

La partie logique (requêtes relationnelle) est assurée par le moteur relationnel, tandis que la partie physique est assurée par le moteur de stockage. Et c’est bien le moteur de stockage qui doit effectuer la lecture de l’index ou s’il n’y a pas d’index adéquat, effectuer l’opération physique des tri des lignes résultant de la requête relationnelle.

Pour vous en convaincre, voici l’architecture interne de MS SQL Server…
architecture interne de MS SQL Server

Tous les SGBD relationnel sont bâtis sur les mêmes principes de séparation :
- Physique : stockage, indexation, lectures, écritures, verrouillage, gestion des transactions, chargement de données via des fichiers externe, sauvegarde, restauration…
- Logique : analyse grammaticale, vérification des privilèges, transformation diverses (XML, Full-Text, SIG…), algébrisation, optimisation, exécution…

À noter : on trouve parfois le terme ORDER BY à l’intérieur de certains opérateurs. C’est le cas des fonctions de fenêtrage dans la clause OVER, mais le but n’est pas de trier, mais d’opérer la fonction de manière ordonnées et n’a aucune influence sur le tri des lignes du résultat. D’autres SGBDR ont conçu des opérations similaires avec des moyens plus ou moins bricolés, entretenant le confusion. Il en est ainsi par exemple de l’horrible opérateur TOP n de MS SQL Server ! D’où la confusion…

Le site web sur le SQL et les SGBDR

MVP Microsoft SQL Server


Frédéric Brouard, alias SQLpro, ARCHITECTE DE DONNÉES
Expert  S.G.B.D  relationnelles   et   langage  S.Q.L
Moste  Valuable  Professionnal  Microsoft  SQL Server
Société SQLspot  :  modélisation, conseil, formation,
optimisation,  audit,  tuning,  administration  SGBDR
Enseignant: CNAM PACA, ISEN Toulon, CESI Aix en Prov.

L’ntreprise SQL Spot

3 réflexions au sujet de « Pourquoi la clause ORDER BY… est-elle interdite au sein d’une requête ? »

    1. Avatar de SQLproSQLpro Auteur de l’article

      Trier un ensemble n’a pas de sens…. Prenez par exemple un ensemble de légumes. Vous pouvez faire des sous ensemble par type (carottes, poireaux, pomme de terre…), vous pouvez comparez par des caractéristiques (couleurs, poids….) mais vous ne pouvez pas globalement trier les éléments de l’ensemble !
      Rien ne vous empêche cependant d’énumérer les légumes dans un certains ordre (par exemple du plus pesant au plus léger); Mais pour autant vous n’avez pas ordonné les légumes entre eux. Vous avez simplement trié sur une caractéristiques…. Il y a donc autant de « tri » possible en fonction des attributs que vous exprimerez pour vos objets, mais cela n’a pas résolu le problème de l’ordre « global » de chaque objet dans l’ensemble !
      Bref, revoyez vos cours de mathématique !

  1. Avatar de CinePhilCinePhil

    Pour compléter ton propos, je pense qu’il est inutile de mettre une clause ORDER BY dans une vue puisque l’un des principaux buts de la vue est d’être requêtée comme une table, donc, en quelque sorte, d’ajouter à sa requête SQL intrinsèque des restrictions (WHERE) des groupages (GROUP BY) ou même de ne sélectionner que des colonnes qui ne sont pas dans le ORDER BY !

    Imaginons ainsi une vue sur les utilisateurs actuellements connectés avec une clause ORDER BY pour avoir le plus récemment connecté en premier :

    CREATE VIEW v_utilisateurs_connectes AS
    SELECT u.uti_nom, c.cnx_debut_connexion
    FROM utilisateur u
    INNER JOIN connexion c ON c.cnx_id_utilisateur = u.uti_id
    ORDER BY c.cnx_debut_connexion DESC

    Si je veux montrer à l’utilisateur la liste des connectés classés par ordre alphabétique, je vais faire cette requête :

    SELECT uti_nom
    FROM v_utilisateurs_connectes
    ORDER BY uti_nom

    => La clause ORDER BY de la vue est ici totalement inutile !

Laisser un commentaire