Comment SQL Server classe-t-il les résultats lorsque des jointures sont utilisées?

10

Comment SQL Server détermine-t-il l'ordre des enregistrements dans le jeu de résultats de l'exécution des requêtes?

J'essaie d'en faire des têtes ou des queues mais je me retrouve à me gratter la tête. Lorsque je modifie les champs, je sélectionne la commande change également. Lorsque j'exécute le SQL ci-dessous avec un, SELECT *j'obtiens les mêmes enregistrements mais dans un ordre très différent.

 SELECT TOP (900)
    AD.ATTACHMENTID,
    AD.NAME,
    AD.ISINLINE,
    AD.INSERTEDDATETIME,
    ATMT.ATTACHMENTBLOB,
    U.UFID
  FROM ATTACHMENTDETAIL AD WITH (NOLOCK)
  INNER JOIN MESSAGEATTACHMENT MA ON MA.ATTACHMENTID = AD.ATTACHMENTID
  INNER JOIN ATTACHMENT ATMT ON ATMT.ATTACHMENTID = AD.ATTACHMENTID
  INNER JOIN MESSAGE MSG ON MSG.ID = MA.MESSAGEID
  INNER JOIN MESSAGEDETAIL MD ON MD.MESSAGEID = MA.MESSAGEID
  INNER JOIN [USER] U ON U.ID = MD.USERID
  LEFT OUTER JOIN XmlExtractionMapping XM ON MA.MESSAGEID = XM.MessageId
    WHERE AD.FILEBOXTOKEN IS NULL 
    AND (XM.XMLEXTRACTIONDATE IS NOT NULL OR 
         (MSG.MESSAGESOURCEID = 1 AND MD.FolderId <> -4))
    AND AD.ISINLINE = 'FALSE'
kacalapy
la source
6
Quelques commentaires / questions: (1) pourquoi utiliser le bouton turbo magique de la poussière de lutin NOLOCK sur une seule table? Avez-vous envisagé d'utiliser RCSI au lieu de vaudou? (2) pourquoi n'utilisez-vous pas les préfixes de schéma appropriés? Pour les premiers, recherchez sur le Web NOLOCK- vous verrez toutes sortes de raisons pour lesquelles vous ne devriez pas l'utiliser. Pour ce dernier, voir sqlblog.com/blogs/aaron_bertrand/archive/2009/10/11/…
Aaron Bertrand
RCSI? s'il vous plaît expliquer ...
kacalapy
2
RCSI = Lire l'isolement de l'instantané validé. Voir stackoverflow.com/questions/816650/…
Aaron Bertrand
Sans ORDER BYclause, SQL Server (et tout autre SGBDR) fait ce qu'il ressent .
Nick Chammas

Réponses:

17

Puisque vous n'avez pas dit à SQL Server comment ordonner les résultats, il est libre de le faire de la manière la plus efficace. De cette façon, cela dépendra du type le moins cher à trier, et les colonnes que vous sélectionnerez le conduiront car cela dépend à son tour du ou des index les moins chers à utiliser pour obtenir les informations demandées par la requête. Cela peut changer d'exécution en exécution non seulement en changeant le texte de la requête, mais aussi par des choses comme les modifications de données, les mises à jour des statistiques, freeproccache, les service packs, les correctifs, etc. Cela est particulièrement volatil avec autant de tables impliquées si les données sous-jacentes changent rapidement , comme c'est généralement le cas dans les applications OLTP.

Si vous voulez un ordre prévisible, pourquoi ne l'utilisez-vous pas ORDER BYsur la requête? Comme il est écrit, les spécifie SQL toutes les 900 lignes sont acceptables, dans un ordre quelconque.

Même si, dans de nombreux cas, vous voyez le même ordre encore et encore pour la même requête, il n'y a aucune garantie sauf si vous le dites ORDER BY <something>.

Aaron Bertrand
la source