web-dev-qa-db-fra.com

L'ordre d'une instruction SQL Select sans clause Order By

Comme je le sais, à partir de la théorie de la base de données relationnelle, une instruction select sans order by la clause doit être considérée comme n'ayant pas d'ordre particulier. Mais en fait dans SQL Server et Oracle (j'ai testé sur ces 2 plates-formes), si je fais une requête à partir d'une table sans order by clause plusieurs fois, j'obtiens toujours les résultats dans le même ordre. Peut-on se fier à ce comportement? N'importe qui peut aider à expliquer un peu?

40
Just a learner

Non, ce comportement ne peut être invoqué. L'ordre est déterminé par la façon dont le planificateur de requêtes a décidé de créer l'ensemble de résultats. les requêtes simples comme select * from foo_table sont susceptibles d'être renvoyées dans l'ordre de leur stockage sur le disque, qui peut être dans l'ordre de la clé primaire ou l'ordre dans lequel elles ont été créées, ou dans un autre ordre aléatoire. des requêtes plus complexes, telles que select * from foo where bar < 10 peuvent à la place être renvoyées dans l'ordre d'une colonne différente, basée sur une lecture d'index, ou par l'ordre des tables, pour une analyse de table. des requêtes encore plus élaborées, avec plusieurs conditions where, des clauses group by, unions, seront dans l'ordre que le planificateur décidera de générer le plus efficacement.

L'ordre pourrait même changer entre deux requêtes identiques simplement en raison des données qui ont changé entre ces requêtes. une clause "where" peut être satisfaite par un balayage d'index dans une requête, mais des insertions ultérieures pourraient rendre cette condition moins sélective, et le planificateur pourrait décider d'effectuer une requête ultérieure à l'aide d'un balayage de table.


Pour mettre un point plus fin là-dessus. Les systèmes SGBDR ont le mandat de vous donner exactement ce que vous avez demandé, aussi efficacement que possible. Cette efficacité peut prendre de nombreuses formes, notamment en minimisant IO (à la fois sur le disque et sur le réseau pour vous envoyer des données), en minimisant le processeur et en conservant la petite taille de son ensemble de travail (en utilisant des méthodes qui nécessitent un stockage temporaire minimal).

sans clause ORDER BY, vous n'aurez pas demandé exactement pour un ordre particulier, et donc le SGBDR vous donnera ces lignes dans un ordre qui (peut-être) correspond à un aspect coïncident de la requête, basée sur l'algorithme que le SGBDR s'attend à produire les données le plus rapidement.

Si vous vous souciez de l'efficacité, mais pas de l'ordre, ignorez la clause ORDER BY. Si vous vous souciez de la commande mais pas de l'efficacité, utilisez la clause ORDER BY.

Puisque vous vous souciez réellement de LES DEUX utilisez ORDER BY Puis ajustez soigneusement votre requête et votre base de données pour qu'elle soit efficace.

Non, vous ne pouvez pas vous fier à obtenir les résultats dans le même ordre à chaque fois. J'ai découvert cela en travaillant sur une page Web avec une grille paginée. Lorsque je suis allé à la page suivante, puis à la page précédente, la page précédente contenait différents enregistrements! J'étais totalement mystifié.

Pour des résultats prévisibles, vous devez alors inclure un ORDER BY. Même dans ce cas, s'il existe des valeurs identiques dans les colonnes spécifiées, vous pouvez obtenir des résultats différents. Vous devrez peut-être ORDER BY champs dont vous ne pensiez pas vraiment avoir besoin, juste pour obtenir un résultat prévisible.

7
DOK

Tom Kyte a un bête noire sur ce sujet . Pour une raison quelconque, les gens sont fascinés par cela et continuent d'essayer de trouver des cas où vous pouvez vous fier à une commande spécifique sans spécifier ORDER BY. Comme d'autres l'ont dit, vous ne pouvez pas. Voici n autre fil amusant sur le sujet sur le site Web AskTom.

4
DCookie

La bonne réponse

Il s'agit d'une nouvelle réponse ajoutée pour corriger l'ancienne. J'ai une réponse de Tom Kyte et je la poste ici:

Si vous voulez trier les lignes, VOUS DEVEZ UTILISER UNE COMMANDE. Non si, et, ou mais à ce sujet. période. http://tkyte.blogspot.ru/2005/08/order-in-court.html Vous devez passer une commande sur cet IOT. Les lignes sont triées en blocs de feuilles, mais les blocs de feuilles ne sont pas stockés triés. analyse complète rapide = lignes non triées.

https://Twitter.com/oracleasktom/status/625318150590980097

https://Twitter.com/oracleasktom/status/625316875338149888


La mauvaise réponse

( Attention ! La réponse originale à la question a été placée ci-dessous ici uniquement pour le plaisir de la histoire. C'est une mauvaise réponse. La bonne réponse est placée au-dessus)

Comme Tom Kyte l'a écrit dans l'article mentionné précédemment:

Vous devriez considérer une table organisée en tas comme une grande collection de lignes non ordonnée. Ces lignes apparaîtront dans un ordre apparemment aléatoire, et selon les autres options utilisées (requête parallèle, différents modes d'optimisation, etc.), elles peuvent apparaître dans un ordre différent avec la même requête. Ne comptez jamais sur l'ordre des lignes d'une requête à moins d'avoir une instruction ORDER BY sur votre requête!

Mais notez qu'il ne parle que des tables organisées en tas. Mais il existe également des tables organisées en index. Dans ce cas, vous pouvez compter sur l'ordre de la sélection sans ORDER BY car l'ordre est implicitement défini par la clé primaire. C'est vrai pour Oracle.

Pour les index cluster SQL Server (tables organisées en index) créés par défaut. Il est également possible d'aligner les informations du magasin PostgreSQL par index. Plus d'informations peuvent être trouvées ici

MISE À JOUR: Je vois qu'il y a un vote négatif sur ma réponse. J'essaierais donc d'expliquer un peu mon propos. Dans la section Présentation des tables organisées par index il y a une phrase:

Dans une table organisée par index, les lignes sont stockées dans un index défini sur la clé primaire de la table ... Les tables organisées par index sont utiles lorsque des données associées doivent être stockées ensemble ou que les données doivent être physiquement stockées dans un ordre spécifique.

http://docs.Oracle.com/cd/E25054_01/server.1111/e25789/indexiot.htm#CBBJEBIH

En raison de l'index, toutes les données sont stockées dans un ordre spécifique, je pense que c'est la même chose pour Pg. http://www.postgresql.org/docs/9.2/static/sql-cluster.html

Si vous n'êtes pas d'accord avec moi, merci de me donner un lien sur la documentation. Je serai heureux de savoir qu'il y a quelque chose à apprendre pour moi.

1
Alexander Myshov