具有聚集索引的表按唯一非聚集索引隱式排序
我有一個表格,可以擷取使用者正在執行的主機平台。該表的定義很簡單:
IF OBJECT_ID('[Auth].[ActivityPlatform]', 'U') IS NULL BEGIN CREATE TABLE [Auth].[ActivityPlatform] ( [ActivityPlatformId] [tinyint] IDENTITY(1,1) NOT NULL ,[ActivityPlatformName] [varchar](32) NOT NULL ,CONSTRAINT [PK_ActivityPlatform] PRIMARY KEY CLUSTERED ([ActivityPlatformId] ASC) ,CONSTRAINT [UQ_ActivityPlatform_ActivityPlatformName] UNIQUE NONCLUSTERED ([ActivityPlatformName] ASC) ) ON [Auth]; END; GO
它儲存的數據是基於使用來自其瀏覽器的資訊的 JavaScript 方法列舉的(我知道的不多,但如果需要,可以找到):
但是,當我在
SELECT
沒有顯式的情況下執行基本ORDER BY
操作時,執行計劃顯示它正在使用UNIQUE NONCLUSTERED
索引而不是索引進行排序CLUSTERED
。SELECT * FROM [Auth].[ActivityPlatform]
當明確指定 時
ORDER BY
,它正確地按 排序ActivityPlatformId
。SELECT * FROM [Auth].[ActivityPlatform] ORDER BY [ActivityPlatformId]
DBCC SHOWCONTIG('[Auth].[ActivityPlatform]') WITH ALL_LEVELS, TABLERESULTS
顯示沒有表碎片。我錯過了什麼可能導致這種情況?我想了很久,表是在聚集索引上創建的,它應該自動隱式排序,而不需要指定
ORDER BY
. SQL Server 在選擇 UQ 時的偏好是什麼?我需要在表的創建中指定什麼嗎?
不,排序不是隱含的,不應依賴。事實上,在第一個工具提示中,您可以看到它明確指出
Ordered = False
. 這意味著 SQL Server 根本沒有做任何事情來實現任何排序。你觀察到的只是它發生的事情,而不是它試圖做的事情。如果您希望能夠預測可靠的排序順序,請輸入
ORDER BY
. 時期。當您不添加時您可能會觀察到的內容ORDER BY
可能很有趣,但不能依賴它來保持一致。事實上,在這篇文章中,參見#3,我展示了查詢的輸出如何通過其他人添加索引而發生變化。SQL Server 在選擇 UQ 時的偏好是什麼?
索引包含集群鍵,因此
UNIQUE NONCLUSTERED
它覆蓋了查詢。在這種情況下,您的表只有兩列,因此聚集索引和非聚集索引包含相同的數據(只是排序不同)。它們的大小相同,因此優化器可以選擇其中一個。它選擇非聚集索引是一個實現細節。我稱之為“拋硬幣”。