Pourquoi SQL Server ne garantit pas les résultats de tri sans ORDER BY

Rebonjour. En juin, OTUS lance à nouveau le cours «MS SQL Server Developer» , traditionnellement à la veille du début du cours, nous commençons à partager avec vous des informations sur le sujet.




Si votre requête ne contient pas ORDER BY, vous ne pouvez pas être sûr que le tri des résultats ne changera pas au fil du temps.

Bien sûr, au début, tout sera assez prévisible, mais à mesure que des changements se produisent (dans les index, les tables, la configuration du serveur, la quantité de vos données), vous pouvez rencontrer des surprises désagréables.

Commençons par quelque chose de simple: faites un SELECT pour la table Users de la base de données Stack Overflow. Cette table a un index de cluster pour la colonne Id, qui commence à un et augmente à un billion. Pour cette requête, les données sont renvoyées dans l'ordre de l'index clusterisé:



mais si vous créez un index sur DisplayName et Location, SQL Server décide soudainement d'utiliser un nouvel index, pas clusterisé:



voici le plan d'exécution:



pourquoi SQL Server a décidé d'utiliser cet index, bien qu'il n'ait pas besoin d'être trié par DisplayName et emplacement? Parce que cet index est la plus petite copie des données à obtenir. Regardons la taille des indices avec sp_BlitzIndex:



L'index cluster (CX / PK) a environ 8,9 millions de lignes et sa taille est de 1,1 Go .

Dans l'index non ordonnés en clusters pour DisplayName, L' emplacement est également environ 8,9 millions de lignes, mais sa taille est seulement 368 Mo . Si vous devez effectuer une analyse pour obtenir les résultats de la requête, alors pourquoi ne pas choisir la plus petite source de données, car elle sera plus rapide. C'est pour cette raison que SQL Server l'a fait.

"Oui, mais ma demande contient OERE."


Ok, maintenant que nous avons un index pour DisplayName et Location, essayons une requête qui recherche un nom spécifique (DisplayName). Les résultats sont triés par DisplayName:



Le plan d'exécution montre que l'index est utilisé par DisplayName et Location:



Mais si vous regardez une valeur différente, les résultats ne seront plus triés par DisplayName:



SQL Server a constaté qu'Alex a un index cluster beaucoup plus raisonnable Analyser au lieu de la recherche d'index + recherche de clé:



même dans ces cas très simples, vous ne pouvez pas garantir que SQL Server utilisera toujours la copie des données que vous attendez.

Récemment, j'ai rencontré des cas beaucoup plus compliqués:

  • Suppression de l'index utilisé dans la requête
  • (Forced Parameterization), , SQL Server
  • (Compatibility Level) (Cardinality Estimator), .



.



All Articles