W jaki sposób wyniki programu SQL Server są wyświetlane, gdy używane są sprzężenia?

10

W jaki sposób SQL Server określa kolejność rekordów w zestawie wyników wykonania zapytania?

Próbuję zrobić z niego głowy lub ogony, ale drapię się po głowie. Kiedy zmieniam pola, wybieram kolejność, zmienia się również. Kiedy wykonuję poniższy SQL za pomocą a SELECT *, otrzymuję te same rekordy, ale w znacznie innej kolejności.

 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
źródło
6
Kilka komentarzy / pytań: (1) po co używać magicznego przycisku turkusowego pixie-pyłu NOLOCK tylko na jednym stole? Czy rozważałeś użycie RCSI zamiast voodoo? (2) dlaczego nie używasz odpowiednich prefiksów schematu? W przypadku pierwszego z nich wyszukaj w Internecie NOLOCK- zobaczysz wszelkiego rodzaju powody, dla których nie powinieneś go używać. Aby zapoznać się z tym drugim, zobacz sqlblog.com/blogs/aaron_bertrand/archive/2009/10/11/…
Aaron Bertrand
RCSI? proszę wyjaśnić ...
kacalapy
2
RCSI = Odczyt zatwierdzonej izolacji migawki. Zobacz stackoverflow.com/questions/816650/…
Aaron Bertrand
Bez ORDER BYklauzuli SQL Server (i inne RDBMS) robi, co chce .
Nick Chammas

Odpowiedzi:

17

Ponieważ nie powiedziałeś SQL Serverowi, w jaki sposób zamówić wyniki, możesz to zrobić w najbardziej efektywny sposób. W ten sposób będzie zależeć od tego, co jest najtańsze do sortowania, a wybrane kolumny będą je napędzać, ponieważ to z kolei zależy od najtańszych indeksów, które zostaną użyte do uzyskania informacji wymaganych przez zapytanie. Może to zmienić się z wykonania na wykonanie nie tylko poprzez zmianę tekstu zapytania, ale także przez takie zmiany danych, aktualizacje statystyk, freeproccache, dodatki Service Pack, poprawki itp. Jest to szczególnie niestabilne przy tak dużej liczbie tabel, jeśli dane podstawowe szybko się zmieniają , jak to zwykle bywa w aplikacjach OLTP.

Jeśli potrzebujesz przewidywalnego zamówienia, dlaczego nie użyjesz ORDER BYgo w zapytaniu? Jak napisano, SQL określa, że dowolne 900 wierszy jest akceptowanych, w dowolnej kolejności.

Chociaż w wielu przypadkach wciąż pojawia się to samo zamówienie dla tego samego zapytania, nie ma gwarancji, chyba że powiesz ORDER BY <something>.

Aaron Bertrand
źródło