Sql-Server
您期望特定順序的所有查詢都應該包含 ORDER BY 子句嗎?
為了更好地理解 SQL Server 查詢處理器,我一直在思考
ORDER BY
子句是如何工作的,以及 SQL Server 如何提供結果。對於任何給定的數據集,SQL Server 似乎將以完全相同的順序提供結果,這些數據集保持不變並且永遠不會改變。一旦你引入了任何類型的不確定性,比如開發人員改變了一些東西,結果的順序就不能再期望是相同的了。
僅以相同的順序查看結果,每次按下
F5
並不能保證您期望的結果。嘗試這個:
USE TempDB; DROP TABLE TestOrderBy; DROP TABLE TestOrderBy2; CREATE TABLE TestOrderBy ( ID INT NOT NULL CONSTRAINT PK_TestOrderBy PRIMARY KEY CLUSTERED IDENTITY(1,1) , SomeData varchar(255) ); INSERT INTO TestOrderBy (SomeData) VALUES ('E'); INSERT INTO TestOrderBy (SomeData) VALUES ('D'); INSERT INTO TestOrderBy (SomeData) VALUES ('C'); INSERT INTO TestOrderBy (SomeData) VALUES ('B'); INSERT INTO TestOrderBy (SomeData) VALUES ('A'); CREATE TABLE TestOrderBy2 ( ID INT NOT NULL CONSTRAINT PK_TestOrderBy2 PRIMARY KEY CLUSTERED IDENTITY(1,1) , SomeData varchar(255) ); INSERT INTO TestOrderBy2 (SomeData) VALUES ('E'); INSERT INTO TestOrderBy2 (SomeData) VALUES ('D'); INSERT INTO TestOrderBy2 (SomeData) VALUES ('C'); INSERT INTO TestOrderBy2 (SomeData) VALUES ('B'); INSERT INTO TestOrderBy2 (SomeData) VALUES ('A'); SELECT SomeData FROM TestOrderBy UNION ALL SELECT SomeData FROM TestOrderBy2; CREATE INDEX IX_TestOrderBy_SomeData ON TestOrderBy (SomeData); CREATE INDEX IX_TestOrderBy2_SomeData ON TestOrderBy2 (SomeData); SELECT SomeData FROM TestOrderBy UNION ALL SELECT SomeData FROM TestOrderBy2;
結果:
如您所見,在查詢中選擇的欄位上添加一個簡單的索引會改變結果的順序。
從這裡開始,
ORDER BY
除非我真的不在乎,否則我會添加。
我想到了一個更簡單的複制:
CREATE TABLE #x(z CHAR(1)); CREATE TABLE #y(z CHAR(1)); INSERT #x SELECT 'O'; INSERT #x SELECT 'R'; INSERT #x SELECT 'D'; INSERT #y SELECT 'E'; INSERT #y SELECT 'R'; SELECT z FROM #x UNION ALL SELECT z FROM #y;
結果:
O R D E R
現在添加一個索引:
CREATE CLUSTERED INDEX z ON #x(z); SELECT z FROM #x UNION ALL SELECT z FROM #y;
結果:
D -| O -|- ordered based on the clustered index, not how originally inserted R -| E R
這仍然會產生來自#x 的前三行和來自#y 的最後兩行,因此仍然不能證明 SQL Server 可能會以不同於查詢中物理佈局的順序返回這些整個查詢(只是你可以’ t 依賴於這些集合內的排序)。但顯然,這種神話般的“遵守一次命令,永遠是真的”的說法需要被扼殺。
底線:不要依賴觀察到的順序。如果您想要某種排序,請使用 ORDER BY。