Ik weet niet zeker wat je hiervan vindt ORDER BY
presteert? Zelfs als je doe zet ORDER BY
in de weergave op een legale manier (bijvoorbeeld door een TOP
. toe te voegen clausule), als u gewoon uit de weergave selecteert, b.v. SELECT * FROM dbo.TopUsersTest;
zonder een ORDER BY
clausule staat het SQL Server vrij om de rijen op de meest efficiënte manier te retourneren, wat niet noodzakelijkerwijs overeenkomt met de volgorde die u verwacht. Dit komt omdat ORDER BY
is overbelast, in die zin dat het twee doelen probeert te dienen:om de resultaten te sorteren en om te dicteren welke rijen moeten worden opgenomen in TOP
. In dit geval TOP
wint altijd (hoewel je, afhankelijk van de index die is gekozen om de gegevens te scannen, kunt opmerken dat je bestelling werkt zoals verwacht - maar dit is gewoon toeval).
Om te bereiken wat je wilt, moet je je ORDER BY
. toevoegen clausule toe aan de query's die gegevens uit de weergave halen, niet aan de code van de weergave zelf.
Dus je weergavecode zou gewoon moeten zijn:
CREATE VIEW [dbo].[TopUsersTest]
AS
SELECT
u.[DisplayName], SUM(a.AnswerMark) AS Marks
FROM
dbo.Users_Questions AS uq
INNER JOIN [dbo].[Users] AS u
ON u.[UserID] = us.[UserID]
INNER JOIN [dbo].[Answers] AS a
ON a.[AnswerID] = uq.[AnswerID]
GROUP BY u.[DisplayName];
De ORDER BY
is zinloos en zou dus niet eens moeten worden opgenomen.
Ter illustratie, met AdventureWorks2012, hier is een voorbeeld:
CREATE VIEW dbo.SillyView
AS
SELECT TOP 100 PERCENT
SalesOrderID, OrderDate, CustomerID , AccountNumber, TotalDue
FROM Sales.SalesOrderHeader
ORDER BY CustomerID;
GO
SELECT SalesOrderID, OrderDate, CustomerID, AccountNumber, TotalDue
FROM dbo.SillyView;
Resultaten:
SalesOrderID OrderDate CustomerID AccountNumber TotalDue
------------ ---------- ---------- -------------- ----------
43659 2005-07-01 29825 10-4020-000676 23153.2339
43660 2005-07-01 29672 10-4020-000117 1457.3288
43661 2005-07-01 29734 10-4020-000442 36865.8012
43662 2005-07-01 29994 10-4020-000227 32474.9324
43663 2005-07-01 29565 10-4020-000510 472.3108
En u kunt aan het uitvoeringsplan zien dat de TOP
en ORDER BY
zijn absoluut genegeerd en weggeoptimaliseerd door SQL Server:
Er is geen TOP
operator helemaal niet, en geen soort. SQL Server heeft ze volledig geoptimaliseerd.
Als u nu de weergave wijzigt in ORDER BY SalesID
, krijg je dan toevallig de volgorde die de weergave aangeeft, maar alleen - zoals eerder vermeld - bij toeval.
Maar als u uw buitenste zoekopdracht wijzigt om de ORDER BY
. uit te voeren je wilde:
SELECT SalesOrderID, OrderDate, CustomerID, AccountNumber, TotalDue
FROM dbo.SillyView
ORDER BY CustomerID;
U krijgt de resultaten geordend zoals u dat wilt:
SalesOrderID OrderDate CustomerID AccountNumber TotalDue
------------ ---------- ---------- -------------- ----------
43793 2005-07-22 11000 10-4030-011000 3756.989
51522 2007-07-22 11000 10-4030-011000 2587.8769
57418 2007-11-04 11000 10-4030-011000 2770.2682
51493 2007-07-20 11001 10-4030-011001 2674.0227
43767 2005-07-18 11001 10-4030-011001 3729.364
En het plan is nog steeds geoptimaliseerd weg de TOP
/ORDER BY
in de weergave, maar er is een sortering toegevoegd (zonder kleine kosten, let wel) om de resultaten te presenteren, gesorteerd op CustomerID
:
Dus, moraal van het verhaal, zet geen ORDER BY in views. Zet ORDER BY in de zoekopdrachten die ernaar verwijzen. En als het sorteren duur is, kunt u overwegen een index toe te voegen/aan te passen om dit te ondersteunen.