Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Domyślna kolejność wierszy w zapytaniu SELECT — SQL Server 2008 vs SQL 2012

Musisz wrócić i dodać ORDER BY klauzul w kodzie, ponieważ bez nich kolejność nigdy nie jest gwarantowana. W przeszłości miałeś „szczęście”, że zawsze dostawałeś to samo zamówienie, ale nie dlatego, że SQL Server 2008 i tak je gwarantował. Najprawdopodobniej miało to związek z twoimi indeksami lub sposobem przechowywania danych na dysku.

Jeśli przeniosłeś się na nowy host po uaktualnieniu, sama różnica w konfiguracji sprzętu mogła zmienić sposób wykonywania zapytań. Nie wspominając już o tym, że nowy serwer przeliczałby statystyki dotyczące tabel, a optymalizator zapytań SQL Server 2012 prawdopodobnie robi rzeczy nieco inaczej niż ten w SQL Server 2008.

Błędem jest to, że możesz polegać na kolejności zestawu wyników w SQL bez wyraźnego określenia kolejności, w jakiej chcesz. Wyniki SQL NIGDY mieć zamówienie, na którym możesz polegać bez użycia ORDER BY klauzula. SQL jest zbudowany wokół teorii mnogości. Wyniki zapytania są zasadniczo zestawami (lub wieloma zestawami).

Itzik Ben-Gan podaje dobry opis teorii mnogości w odniesieniu do SQL w swojej książce Microsoft SQL Server 2012 T-SQL Fundamentals

Teoria mnogości, wywodząca się od matematyka Georga Cantora, jest jedną z gałęzi matematycznych, na których opiera się model relacyjny. Kantorowska definicja zbioru jest następująca:

Przez „zbiór” rozumiemy dowolny zbiór M w całość określonych, odrębnych obiektów m (które nazywamy „elementami” M) naszej percepcji lub naszej myśli. - Joseph W. Dauben i Georg Cantor (PrincetonUniversity Press, 1990)

Po dokładnym wyjaśnieniu terminów w definicji Itzik mówi:

To, co pomija definicja zestawu przez Cantora, jest prawdopodobnie równie ważne, jak to, co zawiera. Zauważ, że definicja nie wymienia żadnej kolejności wśród elementów zestawu. Kolejność, w jakiej wyświetlane są elementy zestawu, nie jest istotna. Formalna notacja do wyliczania elementów zbioru wykorzystuje nawiasy klamrowe:{a, b, c}. Ponieważ kolejność nie ma znaczenia, możesz wyrazić ten sam zestaw, co {b, a, c} lub {b, c, a}. Przeskakując do zbioru atrybutów (w SQL nazywanych kolumnami), które składają się na nagłówek arelacji (w SQL nazywanej tabelą), element ma być identyfikowany przez nazwę, a nie pozycję porządkową. Podobnie rozważmy zbiór krotek (nazywanych przez SQL wierszami), które tworzą treść relacji; element jest identyfikowany przez swoje kluczowe wartości, a nie przez pozycję. Wielu programistów ma trudności z przystosowaniem się do idei, że w odniesieniu do zapytań do tabel nie ma kolejności między wierszami. Innymi słowy, zapytanie do tabeli może zwrócić wiersze w dowolnej kolejności chyba że wyraźnie zażądasz sortowania danych w określony sposób, na przykład w celach prezentacyjnych.

Jednak niezależnie od akademickiej definicji zestawu, nawet implementacja na serwerze SQL nigdy nie gwarantowała żadnego porządku w wynikach. Ten wpis na blogu MSDN z 2005 r. autorstwa członka zespołu optymalizatora zapytań stwierdza, że ​​nie należy w ogóle polegać na kolejności operacji pośrednich.

Zasady zmiany kolejności mogą i będą naruszać to założenie (i robią to, gdy jest to niewygodne dla dewelopera;). Proszę zrozumieć, że kiedy zmieniamy kolejność operacji, aby znaleźć bardziej wydajny plan, możemy spowodować, że zachowanie porządkowania zmieni się dla węzłów pośrednich w drzewie. Jeśli umieścisz w drzewie operację, która zakłada określoną kolejność pośrednią, może się ona zepsuć.

Ten wpis na blogu autorstwa Conora Cunninghama (architekt, SQL Server Core Engine) „Brak pasów bezpieczeństwa — oczekiwanie zamówienia bez ORDER BY” dotyczy programu SQL Server 2008. Ma on tabelę z 20 tys. wierszy z pojedynczym indeksem, który wydaje się zawsze zwracać wiersze w to samo zamówienie. Dodawanie ORDER BY do zapytania nie zmienia nawet planu wykonania, więc dodanie jednego nie powoduje zwiększenia kosztów zapytania, jeśli optymalizator zda sobie sprawę, że go nie potrzebuje. Ale kiedy doda kolejne 20 tys. wierszy do tabeli, nagle plan zapytań się zmieni i teraz używa równoległości i wyniki nie są już uporządkowane!

Trudność polega na tym, że żaden użytkownik zewnętrzny nie ma rozsądnego sposobu, aby wiedzieć, kiedy plan się zmieni. Przestrzeń wszystkich planów jest ogromna i aż do rozmyślania boli cię głowa. Optymalizator SQL Server zmieni plany, nawet dla prostych zapytań, jeśli zmieni się wystarczająca liczba parametrów. Możesz mieć szczęście i nie dokonać zmiany planu, lub możesz po prostu nie myśleć o tym problemie i dodać ORDER BY.

Jeśli potrzebujesz więcej przekonywania, przeczytaj te posty:

  • Bez ORDER BY nie ma domyślnej kolejności sortowania. - Aleksander Kuzniecow
  • Porządek w sądzie! - Thomas Kyte
  • Kolejność zestawu wyników w SQL — Timothy Wiseman



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Czy posiadanie „LUB” w warunku INNER JOIN to zły pomysł?

  2. Zmień nazwę kolumny w SQL Server (T-SQL)

  3. Klient SQL dla Mac OS X, który współpracuje z MS SQL Server

  4. Modyfikowanie harmonogramu agentów serwera SQL (T-SQL)

  5. Optymalizacja TempDB:unikanie wąskich gardeł i problemów z wydajnością