Sql-Server

您期望特定順序的所有查詢都應該包含 ORDER BY 子句嗎?

  • February 23, 2022

為了更好地理解 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。

另外,請閱讀 SQL 團隊中非常聰明的人 Conor Cunningham 的這篇文章

引用自:https://dba.stackexchange.com/questions/39345