SQL meilleures pratiques pour traiter avec ordre de tri par défaut

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

D'après ma propre expérience, il semble que le SGBD commande toujours des données en utilisant FIFO si aucune clause ORDER BY n'est donnée et aucun indice. Toutefois, l'ordre n'est pas garanti. Mais je n'ai jamais vu un SGBD réorganiser des données s'il n'y a pas de changement table.

avez-vous déjà vu un SGBD sélectionner des données dans un ordre non déterministe s'il n'y a pas de changement au tableau?

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

28
demandé sur Jim Ferrans 2009-11-25 00:47:26

10 réponses

Il n'y a pas d'ordre de tri par défaut. Même si la table a un indice groupé, vous n'êtes pas garanti d'obtenir les résultats dans cet ordre. Vous devez utiliser une commande par clause si vous voulez une commande spécifique.

41
répondu HLGEM 2009-11-24 21:50:07

comme le mentionnent les autres affiches, si vous ne spécifiez pas d'ordre de tri, la norme SQL indique que les résultats peuvent être dans n'importe quel ordre que le processeur de requête trouve le plus opportun et efficace.

disons que vous faites une sélection simple non ordonnée pour toutes les lignes d'une table de client, qui n'a pas d'index et pas de clé primaire. Il est tout à fait possible, et même probable, que le processeur de requête va faire un balayage de table droite et produire les lignes dans l'ordre où elles étaient à l'origine insérée (vous donnant le comportement de FIFO que vous avez vu).

si vous ajoutez ensuite un index sur les champs état et ville (dans cet ordre), puis une requête pour WHERE STATE = 'NY' le processeur de requête peut décider qu'il est plus efficace de scanner les entrées index pour L'état = 'NY' plutôt que de faire un balayage complet de la table. Dans ce cas, il se matérialiserait probablement les rangs dans L'état, L'ordre de la ville.

même ceci n'est pas certain. Par exemple, si le processeur de requête a recueilli des statistiques cela montre que presque toutes les valeurs D'état dans votre table sont 'NY' (peut-être parce que la base de données est pour une entreprise de location de matériel basée à Albany), il peut décider que le scanner de table est en fait moins cher que le scanner d'index, et vous verrez à nouveau FIFO.

c'est une bonne idée d'apprendre quelques bases sur la façon dont votre base de données planifie ses requêtes. Vous pouvez utiliser la déclaration EXPLAIN pour voir comment votre SGBD exécuterait n'importe quelle requête donnée, et puis utiliser ceci pour optimiser votre requête, dans certains cas par ordre de grandeur. C'est un fascinant et utile pour apprendre.

17
répondu Jim Ferrans 2009-11-24 22:43:53

si vous voulez que les données ressortent dans un ordre constant, oui - vous devez utiliser ORDER BY .

9
répondu OMG Ponies 2009-11-24 21:50:27

Oui. Il n'y a pas d ' "ordre Par Défaut" sans un ordre de, et il n'y a aucune garantie que vous obtiendrez les données de retour dans FIFO/LIFO ou tout autre ordre.

en ce qui concerne les développeurs utilisant" SELECT id, name FROM table", ils sont soit incompétents, soit ils ne se soucient pas de l'ordre dans lequel quelque chose apparaît.

6
répondu Ken White 2009-11-24 21:50:51

Pas grave SGBD garantit toute commande à moins que permet de spécifier un ORDRE explicite.

tout le reste n'est que pure chance ou anectodal - si vous voulez l'ordre, vous devez spécifier L'ordre par - aucun moyen de contourner cela.

3
répondu marc_s 2009-11-24 21:50:52

si vous voulez que les données soient commandées, la seule façon de garantir quoi que ce soit (avec tous les principaux systèmes RDBMS que je connais, certainement Sql Server et Oracle) est d'inclure une commande par clause. FIFO n'a absolument rien à voir avec les données de la commande est retourné sans une commande par clause, et il n'y a pas un concept de toute sorte D'ordre de tri par défaut. L'ordre de tri par défaut est essentiellement cependant le moteur obtient les données, qui pourraient être dans n'importe quel ordre basé sur des index, mis en cache données, exécution simultanée de requêtes, chargement sur le serveur, etc., etc.

cet autre fil stackoverflow est essentiellement couvrant le même concept en relation avec Sql Server, AlexK blogué un repo pour démontrer le comportement.

3
répondu chadhoc 2017-05-23 10:31:25

même une simple requête comme SELECT ... FROM table peut renvoyer des données dans un ordre différent. Je sais que c'est vrai en théorie, je sais que c'est vrai en pratique, et j'ai vu beaucoup de cas où l'ordre change entre les exécutions subséquentes, même quand aucune modification de données ne se produit dans le tableau.

un exemple typique de changement d'ordre entre les exécutions est lorsque la requête est exécutée en utilisant un plan parallèle. Puisque les opérateurs parallèles renvoient les données comme les threads sous-jacents les produisent, l'ordre des lignes dans le résultat varie entre chaque exécution. Cette situation fait même le simple SELECT dans votre exemple retourner des résultats très différents à chaque fois est exécuté.

3
répondu Remus Rusanu 2009-11-24 21:59:04

D'après mon expérience avec SQL, la plupart du temps Je ne spécifie pas un" ordre 151910920 "par en SQL, parce que les ensembles d'enregistrement sont affichés dans un " côté client " contrôle de type de grille etc. là où le tri dynamique est supporté - dans ce cas la commande par SQL est inutile car il sera vérifié côté client de toute façon.

ceci est également fait côté client parce que la même requête pourrait être utilisée pour afficher les données à différents endroits dans différents ordres.

par conséquent, il est seulement la meilleure pratique de mettre dans un ordre Par, quand

  • l'ordre des données est important; et
  • le tri est plus efficace au niveau des DB.

c'est à dire si le développeur front-end va être "re-tri" de toute façon, il n'y a aucun point, car il est rare d'enregistrer ensemble le temps de traitement.

3
répondu simo.37920 2014-07-10 00:16:21

peut-être que les rédacteurs de ces requêtes SQL que vous lisez ne se soucient pas de l'ordre des données retournées. La meilleure pratique consiste à utiliser où vous devez vous assurer de l'ordre des résultats de retour!

1
répondu Mike Atlas 2009-11-24 21:51:02

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, disons pour les tables de log, avec tri sur Index. Par exemple, je suis généralement intéressé par les dernières lignes de la table log (LIFO) donc je fais DateTime DESC dans l'ordre. J'ai aussi essayé pour le plaisir d'ajouter L'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 en SSMS ...

enter image description here

0
répondu hoggar 2017-05-06 00:14:48