Artykuły

A A A
Drukuj Ekportuj do PDF
Opublikowane: 2012.01.29 23:37 | Dariusz Brejnak | Aktualizacja: 2012.01.29 23:38

ORDER BY w widokach MS SQL Server 2005 i 2008

Pomimo ogólnej wiedzy, że nie stosuje się klauzuli ORDER BY w widokach często zdarza się, że chcemy lub też musimy jej użyć. Przy pierwszej próbie stworzenia prostego widoku z ORDER BY dostajemy błąd. Co za tym się kryje? Jak rozwiązać ten problem, czy da się to go naprawić ?

W pierwszym kroku należy utworzyć tabelę do testów i wypełnić ją danymi.

CREATE TABLE dbo.FOO 
(  ID INT PRIMARY KEY 
 , MyValue INT UNIQUE);
GO 

INSERT INTO dbo.FOO (ID,MyValue) VALUES (1,3); 
INSERT INTO dbo.FOO (ID,MyValue) VALUES (2,2); 
INSERT INTO dbo.FOO (ID,MyValue) VALUES (3,1); 
GO

 

Następnie przystępujemy do utworzenia widoku:

CREATE VIEW vw_FOO(ID,MyValue) 
AS 
SELECT ID 
      ,MyValue 
FROM dbo.FOO 
ORDER BY ID DESC 
GO

 

Przy próbie utworzenia widoku vw_FOO wygenerowany zostaje następujący komunikat błędu:

Komunikat informuje o sytuacjach, w których stosowanie klauzuli ORDER BY jest dozwolone. Jest to np. zastosowanie w zapytaniu tworzącym klauzuli TOP lub FOR XML, wraz z klauzulą ORDER BY. Jeśli w tabeli znajduje się znana liczba wierszy niezmiennych w czasie  (np. 1000), to w celu stworzenia posortowanego widoku można użyć klauzuli TOP (1000). W przypadku zmieniającej się liczby wierszy sensowniej jest zastosowanie klauzuli TOP (100) PERCENT, która wyświetla 100% (czyli wszystkie) wiersze z tabeli.

W wyniku takiego połączenia klauzula ORDER BY uzyskuje nowe znaczeniejako części filtra TOP.

Przypominając składnię TOP

[     TOP (expression)  [PERCENT]    [ WITH TIES ]

]

Dokładne informacje na ten temat można znaleść pod tym adresem http://technet.microsoft.com/en-us/library/ms189463.aspx

Oczywiste więc staje się użycie następującego kodu do utworzenia widoku oraz wywołanie go:

CREATE VIEW dbo.vw_FOO 
AS SELECT TOP (100) PERCENT 
    ID 
  , MyValue 
FROM FOO ORDER BY ID DESC 
GO 

SELECT ID 
     , MyValue 
FROM dbo.vw_FOO 
GO

 

Działa, ale... hmmm... dziwne ?

Utworzyliśmy widok z ORDER BY i TOP, ale wynik nasz świadczy o tym, że klauzula ORDER BY nie zadziałała. Sprawdzimy samo zapytanie.

SELECT TOP 100 PERCENT ID 
                     , MyValue 
FROM FOO 
ORDER BY ID DESC 
GO

 

 

Jak widać wykonanie zapytania z ORDER BY i TOP nie działa wyłącznie w widoku.

Klauzula ORDER BY może (ale nie musi) zostać zignorowana przez optymalizator SQL Server 2005 lub SQL Server 2008.

Jest to znany błąd w MS SQL Server 2008 gdzie w wyniku stosowania klauzul ORDER BY i TOP w widokach uzyskujemy losowy układ wierszy.

Ale dlaczego tak się dzieje ?

Jeżeli przyjrzymy się planom wykonania to zauważymy, że nie ma w nich sortowania. Tworząc oryginalną tabelę FOO zostaje ona utworzona jako sterta (heap) (no clustered index) i nie tworzy ona pomocniczego  indeksu. Patrząc na plan wykonania zapytania zauważymy, że występuje tylko Table Scan. W tym szczególnym przypadku optimizer stwierdza, że klauzula TOP 100 PERCENT całkowicie pokrywa wszystkie wiersze i nie musi wszystkiego przeliczać. Stąd też mamy brak sortowania. 

Można to rozwiązać na dwa sposoby:

Rozwiązanie nr 1

Pierwszy sposób polega na użyciu w klauzuli TOP wartości 99.9999 PERCENT

CREATE VIEW dbo.vw_FOO 
AS 
SELECT TOP (99.99999) PERCENT ID 
                            , MyValue 
FROM dbo.FOO 
ORDER BY ID DESC 
GO

 

ale i tutaj musimy uważać gdyż w zależności od  liczby wierszy w tabeli możemy uzyskać inną ilość wyświetlanych wierszy w widoku. Łatwo to sprawdzić stosując prosty kod:

SELECT COUNT(*) ViewCount 
FROM vw_FOO 
GO 

SELECT COUNT(*) OriginalCount 
FROM dbo.FOO 
GO

 

Jeżeli uzyskamy mniejszą ilość wierszy dla widoku musimy zwiększyć precyzję w klauzuli TOP dopisując więcej cyfr 9 po przecinku (kropce).

Rozwiązanie nr 2

 Należy zainstalować Hot-fix

"FIX: When you query through a view that uses the ORDER BY clause in SQL Server 2008, the result is still returned in random order"

http://support.microsoft.com/kb/926292http://support.microsoft.com/kb/956717/

Linki:

http://blogs.msdn.com/b/queryoptteam/archive/2006/03/24/560396.aspx

http://blog.sqlauthority.com/2009/11/24/sql-server-interesting-observation-top-100-percent-and-order-by/

http://support.microsoft.com/kb/926292

http://support.microsoft.com/kb/956717/

http://technet.microsoft.com/en-us/library/ms189463.aspx


Komentarze 0 Masz uwagi do tej strony? Napisz

Dodaj komentarz

avatar

Zaloguj się lub Zarejestruj się aby wykonać tę czynność.

Autor Dariusz Brejnak
avatar Ekspert WSS
 

MCP, MCTS

Zawodowo swoją przygodę rozpoczął na początku lat 90 jako programista aplikacji bazodanowych.
Na co dzień zajmuje się projektowaniem, programowaniem oraz administrowaniem systemami informatycznymi oraz bazami danych, głównie w oparciu o produkty firmy Microsoft.
Entuzjasta technologii Microsoftu, członek kilku społeczności zorientowanych na: MS SQL Server, Visual Studio, TFS,.NET Framework takich jak: PASS, PLSSUG, WODNUG, Wg-NET, WGUiSW.

Autor kilkudziesięciu artykułów i porad na temat MS SQL Server, Visual Studio.

Absolwent Warszawskiej Wyższej Szkoły Informatyki (WWSI).

Załóż konto
WSS to serwis, który łączy dziesiątki tysięcy specjalistów IT w Polsce, zajmujących się szeroko pojętymi technologiami Microsoft. Portal działa od 2003 roku, i oprócz setek publikacji technicznych, rozwijającego się forum - portal to ludzie, którzy go tworzą. To właśnie z myślą o nich warto codziennie nas odwiedzać.

Dowiedz się więcej o WSS

vGuru - Zostań Guru Wirtualizacji

 

MetroOne

Idź na górę strony