sql >> Databasteknik >  >> RDS >> Sqlserver

Skapa en vy med ORDER BY-satsen

Jag är inte säker på vad du tycker om detta ORDER BY presterar? Även om du gör lägg ORDER BY i vyn på ett lagligt sätt (t.ex. genom att lägga till en TOP klausul), om du bara väljer från vyn, t.ex. SELECT * FROM dbo.TopUsersTest; utan en ORDER BY klausul är SQL Server fri att returnera raderna på det mest effektiva sättet, vilket inte nödvändigtvis matchar den ordning du förväntar dig. Detta beror på att ORDER BY är överbelastad, genom att den försöker tjäna två syften:att sortera resultaten och att diktera vilka rader som ska inkluderas i TOP . I det här fallet, TOP vinner alltid (även om du, beroende på vilket index som valts för att skanna data, kan observera att din beställning fungerar som förväntat - men detta är bara en slump).

För att uppnå det du vill måste du lägga till din ORDER BY klausul till frågorna som hämtar data från vyn, inte till koden för själva vyn.

Så din visningskod bör bara vara:

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];

ORDER BY är meningslöst så bör inte ens inkluderas.

För att illustrera, med hjälp av AdventureWorks2012, här är ett exempel:

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;

Resultat:

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

Och du kan se från exekveringsplanen att TOP och ORDER BY har absolut ignorerats och optimerats bort av SQL Server:

Det finns ingen TOP operatör alls, och ingen sort. SQL Server har optimerat bort dem helt.

Nu, om du ändrar vyn till att säga ORDER BY SalesID , då råkar du bara få den ordning som vyn anger, men bara - som tidigare nämnts - av en slump.

Men om du ändrar din yttre fråga för att utföra ORDER BY du ville ha:

SELECT SalesOrderID, OrderDate, CustomerID, AccountNumber, TotalDue
FROM dbo.SillyView
ORDER BY CustomerID;

Du får resultaten ordnade som du vill:

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

Och planen har fortfarande optimerat bort TOP /ORDER BY i vyn, men en sortering läggs till (till ingen liten kostnad, märk väl) för att presentera resultaten sorterade efter CustomerID :

Så, berättelsens moral, lägg inte ORDER BY i åsikter. Lägg ORDER BY i frågorna som refererar till dem. Och om sorteringen är dyr kan du överväga att lägga till/ändra ett index för att stödja det.



  1. Hur man aktiverar MySQL Query Cache

  2. få id för flera rader infogade i psycopg2

  3. Hur DB_NAME() fungerar i SQL Server

  4. SQL Välj Distinkt