Dans quel ordre les lignes sont-elles extraites sans la clause ORDER BY?

11

Un programmeur teste et compare la même application qui utilise la même structure de base de données et les mêmes données, uniquement dans deux bases de données distinctes, une avec Oracle 8 et une avec Oracle 9.

L'application exécute une requête sans ORDER BY clause.

Il prétend que la requête ORDER-BY-less devrait renvoyer les lignes dans le même ordre dans les deux bases de données.

Je lui dis qu'il n'y a pas de garantie pour la même commande de ligne, sauf si vous fournissez explicitement une clause ORDER BY.

La base de données a les mêmes index et clés. Mais le plan d'explication montre que dans l'une des bases de données, le moteur utilise la clé de l'une des tables jointes tandis que dans l'autre base de données, il utilise une autre.

Il insinue que les deux environnements DB ne sont pas égaux, c'est parce qu'ils ont des statistiques différentes, des moteurs rdbms différents, etc., mais pas parce que je n'ai pas réussi à répliquer tous les index de la base de données d'origine.

Je lui dis qu'il doit explicitement prévoir une ORDER BYclause si l'ordre est vraiment aussi important.

La question

Je peux donc mieux l'expliquer:

Dans quel ordre une requête récupère-t-elle les lignes lorsque vous ne fournissez pas explicitement une clause ORDER BY, et pourquoi cette requête ne renvoie-t-elle pas les lignes dans le même ordre?

Tulains Córdova
la source
3
Ce n'est pas défini. Je ne crois pas que la spécification SQL énonce l'ordre spécifique que les enregistrements doivent être renvoyés, donc cela dépendra de l'implémentation.
Robert Harvey
1
@RobertHarvey C'est exactement pourquoi je lui dis. En fait: par définition, les tables relationnelles ne doivent pas avoir d'ordre particulier.
Tulains Córdova
1
Il peut être judicieux, même sur la même version exacte du logiciel, d'utiliser un index différent, car il peut être plus sélectif en fonction des statistiques d'index qu'il a recueillies pour les données exactes de cette base de données. Vous ne pouvez donc vraiment pas vous fier à la commande si vous ne la spécifiez pas.
psr
De façon réaliste, vous pouvez vous attendre à ce que la première requête par colonne non indexée suive l'ordre "insérer le temps"; par "heure de mise à jour" indexée. Les demandes consécutives peuvent probablement être "entachées" par des résultats mis en cache et donc assez aléatoires; n'en dépendent cependant jamais - elles peuvent changer de version en version, par paramètres, par opérations de mise à jour et par mauvais temps à la pleine lune. "Indéfini" est la bonne réponse, et tout le reste est au mieux des suppositions éclairées.
SF.
1
Les ensembles de résultats renvoyés par RDMBS-es ne sont que cela: des ensembles qui, par définition, n'ont pas d'ordre particulier. Ainsi, le SGBDR peut les renvoyer dans l'ordre qu'il souhaite et modifier à nouveau l'ordre lors de la prochaine exécution de la requête. S'appuyer sur une commande particulière sans clause ORDER BY serait une erreur. J'essaie toujours d'expliquer cela à mes collègues, mais je ne réussis que la moitié du temps: D.
Radu Murzea

Réponses:

25

De Wikipédia :

La clause ORDER BY identifie les colonnes utilisées pour trier les données résultantes et dans quelle direction elles doivent être triées (les options sont ascendantes ou descendantes). Sans clause ORDER BY, l'ordre des lignes renvoyées par une requête SQL n'est pas défini.

Ce n'est donc pas défini.

La spécification SQL n'indique pas l'ordre spécifique auquel les enregistrements doivent être retournés, donc cela dépendra de l'implémentation.

Sans index sur la table, l'ordre raisonnable serait l'ordre dans lequel les enregistrements ont été insérés. Avec une clé primaire définie, l'ordre sensible serait l'ordre de la clé primaire. Mais comme la spécification ANSI ne nécessite pas de commande spécifique, c'est au vendeur de décider, et leur sensibilité peut différer de la vôtre ou de la mienne.

Étant donné que la commande n'est pas indiquée dans la spécification, il n'est pas judicieux de s'appuyer sur le comportement de l'implémentation d'un fournisseur particulier, car elle peut varier d'un fournisseur à l'autre, et le fournisseur peut modifier la commande à tout moment, sans avertissement.

Comme vous l'avez dit, il suffit d'inclure la ORDER BYclause, si l'ordre est important.

Robert Harvey
la source
La requête a plusieurs tables jointes. Ainsi, un moteur de base de données trie l'ensemble de résultats selon un critère et l'autre base de données utilise un autre critère. Évidemment, lorsqu'une clause ORDER BY est fournie, les deux requêtes renvoient les lignes dans l'ordre spécifié.
Tulains Córdova
+1 AFAICR l'ordre est même autorisé à varier chaque fois que vous exécutez une requête donnée sur une instance de base de données particulière.
MarkJ
2
Je dirais que, sans clause ORDER BY, le seul ordre de résultat raisonnable est celui qui crée le moins de frais généraux. Pour les moteurs et les requêtes de stockage DB simples, il s'agit souvent de l'ordre d'insertion (et pour les clés primaires générées de la même manière que l'ordre des clés primaires). Mais dès que vous avez des hachages, je m'attends à ce que l'ordre soit essentiellement aléatoire.
Michael Borgwardt
2

Il est évident que la spécification ne dit pas dans quel ordre les données arrivent, n'a pas fonctionné. Probablement parce qu'il sait que les données se trouvent sur un disque ou en mémoire quelque part et ont donc cela comme ordre. Demandez-lui quel est l'ordre des données calculées à partir de plusieurs tableaux. C'est à dire créer un exemple où vous joignez 4 tables, en faisant un calcul sur 2 d'entre elles et en retournant juste la valeur calculée.

Le moteur renvoie les données dans l'ordre dans lequel il les trouve (en l'absence d'une commande par), mais la façon dont il les trouve dépend de facteurs qui peuvent changer - index, statistiques, caches. Généralement, les données seront dans un ordre cohérent - mais si vous dépendez de la commande, vous devez la demander.

jmoreno
la source