Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Ordre des lignes par défaut dans la requête SELECT - SQL Server 2008 vs SQL 2012

Vous devez revenir en arrière et ajouter ORDER BY clauses à votre code car sans elles la commande n'est jamais garantie. Vous avez eu la "chance" dans le passé d'avoir toujours la même commande, mais ce n'est pas parce que SQL Server 2008 l'a garanti de toute façon. Cela était probablement lié à vos index ou à la manière dont les données étaient stockées sur le disque.

Si vous avez déménagé vers un nouvel hôte lors de la mise à niveau, la seule différence de configuration matérielle aurait pu modifier la façon dont vos requêtes s'exécutent. Sans parler du fait que le nouveau serveur aurait recalculé les statistiques sur les tables et que l'optimiseur de requêtes SQL Server 2012 fait probablement les choses un peu différemment de celui de SQL Server 2008.

C'est une erreur que vous puissiez vous fier à l'ordre d'un jeu de résultats en SQL sans indiquer explicitement l'ordre dans lequel vous le souhaitez. Résultats SQL JAMAIS avoir une commande sur laquelle vous pouvez compter sans utiliser de ORDER BY clause. SQL est construit autour de la théorie des ensembles. Les résultats de la requête sont essentiellement des ensembles (ou multi-ensembles).

Itzik Ben-Gan donne une bonne description de la théorie des ensembles en relation avec SQL dans son livre Microsoft SQL Server 2012 T-SQL Fundamentals

La théorie des ensembles, dont l'origine remonte au mathématicien Georg Cantor, est l'une des branches mathématiques sur lesquelles repose le modèle relationnel. La définition de Cantor d'un ensemble suit :

Par « ensemble », nous entendons toute collection M en un ensemble d'objets définis et distincts m (qui sont appelés les « éléments » de M) de notre perception ou de notre pensée. - Joseph W. Dauben et Georg Cantor (PrincetonUniversity Press, 1990)

Après une explication approfondie des termes de la définition, Itzik poursuit en disant :

Ce que la définition de Cantor d'un ensemble laisse de côté est probablement aussi important que ce qu'il inclut. Notez que la définition ne mentionne aucun ordre parmi les éléments de l'ensemble. L'ordre dans lequel les éléments d'ensemble sont listés n'est pas important. La notation formelle pour lister les éléments d'ensemble utilise des accolades :{a, b, c}. Comme l'ordre n'a aucune importance, vous pouvez exprimer le même ensemble sous la forme {b, a, c} ou {b, c, a}. En passant à l'ensemble d'attributs (appelés colonnes en SQL) qui constituent l'en-tête d'une relation (appelée table en SQL), un élément est censé être identifié par son nom - et non par sa position ordinale. De même, considérons l'ensemble de tuples (appelés lignes par SQL) qui composent le corps de la relation ; un élément est identifié par ses valeurs clés - et non par sa position. De nombreux programmeurs ont du mal à s'adapter à l'idée qu'en ce qui concerne l'interrogation des tables, il n'y a pas d'ordre entre les lignes. En d'autres termes, une requête sur une table peut renvoyer des lignes dans n'importe quel ordre sauf si vous demandez explicitement que les données soient triées d'une manière spécifique, peut-être à des fins de présentation.

Mais quelle que soit la définition académique d'un ensemble, même l'implémentation dans SQL Server n'a jamais garanti un ordre dans les résultats. Ce billet de blog MSDN de 2005 par un membre de l'équipe de l'optimiseur de requête indique que vous ne devez pas du tout vous fier à l'ordre des opérations intermédiaires.

Les règles de réorganisation peuvent et vont violer cette hypothèse (et le font quand cela ne vous convient pas, le développeur ;). Veuillez comprendre que lorsque nous réordonnons les opérations pour trouver un plan plus efficace, nous pouvons modifier le comportement de l'ordre pour les nœuds intermédiaires de l'arborescence. Si vous avez placé une opération dans l'arborescence qui suppose un ordre intermédiaire particulier, elle peut échouer.

Ce billet de blog de Conor Cunningham (architecte, SQL Server Core Engine) "No Seatbelt - Expecting Order without ORDER BY" concerne SQL Server 2008. Il a une table avec 20 000 lignes avec un index unique qui semble toujours renvoyer des lignes dans le même ordre. Ajouter un ORDER BY à la requête ne modifie même pas le plan d'exécution, ce n'est donc pas comme si en ajouter un rendait la requête plus coûteuse si l'optimiseur se rend compte qu'il n'en a pas besoin. Mais une fois qu'il a ajouté 20 000 lignes supplémentaires à la table, le plan de requête change soudainement et utilise maintenant le parallélisme et les résultats ne sont plus ordonnés !

Le plus difficile ici est qu'il n'y a aucun moyen raisonnable pour un utilisateur externe de savoir quand un plan va changer. L'espace de tous les plans est énorme et ça fait mal à la tête de réfléchir. L'optimiseur de SQL Server modifiera les plans, même pour les requêtes simples, si suffisamment de paramètres changent. Vous pouvez avoir de la chance et ne pas avoir de changement de plan, ou vous pouvez simplement ne pas penser à ce problème et ajouter un ORDER BY.

Si vous avez besoin de plus de convictions, lisez simplement ces articles :

  • Sans ORDER BY, il n'y a pas d'ordre de tri par défaut. - Alexandre Kouznetsov
  • Ordonnance au tribunal ! -Thomas Kyte
  • Ordre d'un ensemble de résultats en SQL - Timothy Wiseman