web-dev-qa-db-fra.com

Meilleure pratique SQL pour traiter l'ordre de tri par défaut

J'ai lu beaucoup de code SQL, il semble que le développeur présume que l'ordre de tri par défaut est toujours valable. Par exemple, lors de la création d'une liste de sélection HTML, ils ne feraient que SELECT id, name FROM table sans émettre de clause ORDER BY.

D'après ma propre expérience, il semble que dbms ordonne toujours de commander les données en utilisant FIFO si aucune clause ORDER BY n'est fournie et aucun index. Cependant, la commande n'est pas garantie. Mais je n'ai jamais vu un dbms réordonnant les données s'il n'y avait aucun changement à la table.

Avez-vous déjà rencontré un dbms sélectionnant des données dans un ordre non déterministe s’il n’y avait aucun changement dans la table?

Est-il préférable de toujours mettre une clause ORDER BY? 

29
Yada

Il n'y a pas d'ordre de tri par défaut. Même si la table a un index clusterisé, vous n'êtes pas assuré d'obtenir les résultats dans cet ordre. Vous devez utiliser une clause order by si vous souhaitez une commande spécifique.

46
HLGEM

Comme le mentionnent les autres affiches, si vous ne spécifiez pas d'ordre de tri, le standard SQL indique que les résultats peuvent être dans l'ordre de votre choix, le plus rapidement possible et le plus efficace. 

Supposons que vous fassiez une simple SELECT non ordonnée pour toutes les lignes d'une table CUSTOMER, qui n'a pas d'index ni de clé primaire. Il est tout à fait possible, et même probable, que le processeur de requêtes effectue une analyse de table directe et produise les lignes dans l'ordre dans lequel elles ont été insérées à l'origine (ce qui vous donne le comportement FIFO que vous avez observé).

Si vous ajoutez ensuite un index sur les champs STATE et CITY (dans cet ordre), puis interrogez WHERE STATE = 'NY', le processeur de requête peut décider qu'il est plus efficace d'analyser les entrées d'index pour STATE = 'NY' plutôt que d'effectuer une analyse complète de la table. . Dans ce cas, les lignes seraient probablement matérialisées en ordre STATE, CITY.

Même ce n'est pas certain. Par exemple, si le processeur de requêtes a rassemblé des statistiques montrant que presque toutes les valeurs STATE de votre table sont 'NY' (peut-être parce que la base de données concerne une entreprise de location d'équipement basée à Albany), il peut décider que l'analyse de table est en réalité moins chère. que l'index, et vous verrez à nouveau FIFO.

C'est une bonne idée d'apprendre quelques notions de base sur la manière dont votre base de données planifie ses requêtes. Vous pouvez utiliser l'instruction EXPLAIN pour voir comment votre SGBD exécuterait une requête donnée, puis l'utiliser pour optimiser votre requête, dans certains cas par ordre de grandeur. C'est un domaine fascinant et utile à apprendre.

17
Jim Ferrans

Si vous voulez que les données soient systématiquement ordonnées, vous devez utiliser ORDER BY.

9
OMG Ponies

Oui. Il n'y a pas de "commande par défaut" sans ORDER BY, et rien ne garantit que les données vous seront restituées au format FIFO/LIFO ou de toute autre commande.

En ce qui concerne les développeurs qui utilisent "SELECT id, name FROM table", ils sont soit incompétents, soit ne se soucient pas de l'ordre dans lequel les éléments apparaissent.

6
Ken White

Aucun SGBDR sérieux ne garantit n'importe quel ordre sauf si vous spécifiez un ORDER BY explicite.

Tout le reste n'est que pur hasard ou anectodal - si vous voulez de l'ordre, vous devez spécifier ORDER BY - aucun moyen de contourner cela.

3
marc_s

Si vous voulez que les données soient commandées, le seul moyen de garantir quoi que ce soit (avec chaque système de SGBDR majeur que je sache, définitivement Sql Server et Oracle) est d'inclure une clause ORDER BY. FIFO n'a absolument rien à voir avec les données de commande retournées sans clause ORDER BY, et il n'y a pas de concept d'aucun type d'ordre de tri DEFAULT. L’ordre de tri DEFAULT est en gros le moteur récupère les données, qui peuvent être dans n’importe quel ordre basé sur les index, les données en cache, l’exécution simultanée de requêtes, le chargement sur le serveur, etc., etc.

Cet autre thread stackoverflow couvre en gros le même concept que Sql Server, AlexK a rédigé un blog sur un rapport pour illustrer ce comportement.

3
boydc7

Dans mon expérience avec SQL, la plupart du temps, je ne spécifie pas un ORDER BY en SQL, car les jeux d'enregistrements sont affichés dans un contrôle de type " côté client " etc. où le tri dynamique est pris en charge - dans ce cas, le classement par SQL est inutile car il sera de toute façon vérifié côté client. 

Ceci est également effectué côté client car la même requête peut être utilisée pour afficher les données à des emplacements différents dans des ordres différents.

Par conséquent, la meilleure pratique consiste à insérer un ORDER BY lorsque

  • L'ordre des donnéesESTimportant; et
  • Le tri est plus efficace au niveau de la base de données.

c'est-à-dire que si le développeur front-end va le "re-trier" de toute façon, alors cela ne sert à rien, cela ne sauvera probablement pas le temps de traitement global.

3
simo.37920

Même une simple requête telle que SELECT ... FROM table peut renvoyer des données dans un ordre différent. Je sais que cela est vrai en théorie, dans la pratique, et j'ai vu de nombreux cas où l'ordre change entre les exécutions suivantes, même si aucun changement de données ne se produit dans la table.

Un exemple typique de changement d’ordre entre les exécutions est le cas où la requête est exécutée à l’aide d’un plan parallèle. Étant donné que les opérateurs parallèles renvoient les données à mesure que les threads sous-jacents les produisent, l'ordre des lignes dans le résultat varie entre chaque exécution. Cette situation fait que même le simple SELECT de votre exemple renvoie des résultats très différents à chaque exécution.

3
Remus Rusanu

Peut-être que les rédacteurs des requêtes SQL que vous lisez ne se soucient pas de l'ordre des données retournées. La meilleure pratique consiste à l'utiliser là où vous en avez besoin pour vous assurer que l'ordre des résultats est renvoyé!

1
Mike Atlas

J'écris ceci au cas où quelqu'un voudrait l'utiliser comme je l'ai fait.

Eh bien, je reçois un ordre de tri par défaut satisfaisant, par exemple pour les tables de journal, avec un tri sur Index. Par exemple, les dernières lignes de la table de journalisation (LIFO) m'intéressent donc je mets Date DESC comme ordre. J'ai aussi essayé pour le plaisir d'ajouter Index sur l'autre champ (entier) à côté de la clé primaire et cela a fonctionné.

CREATE TABLE [dbo].[tableA]([DateTime] [datetime] NOT NULL,
CONSTRAINT [PK_tableA] 
PRIMARY KEY CLUSTERED ([DateTime] DESC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]

Ou dans SSMS ...

 enter image description here

0
hoggar