Sql-Server

表的排序是基於聚集索引還是非聚集主鍵?

  • July 5, 2016

我在名稱列上創建了一個帶有主鍵的表,該表的排序基於名稱列

create table TestPrimaryKey (Name varchar(20) primary key,id int identity)

insert into TestPrimaryKey (SomeText) values ('john')
insert into TestPrimaryKey (SomeText) values ('ryan')
insert into TestPrimaryKey (SomeText) values ('jennifer')
insert into TestPrimaryKey (SomeText) values ('martha')
insert into TestPrimaryKey (SomeText) values ('luke')
insert into TestPrimaryKey (SomeText) values ('alex')
insert into TestPrimaryKey (SomeText) values ('wayne')

現在我將主鍵上的聚集索引更改為非聚集索引,但排序仍然基於名稱列

   begin tran
   alter table dbo.TestPrimaryKey drop constraint PK__TestPrim__BC2905030401D947
   alter table dbo.TestPrimaryKey add constraint PK__TestPrim__BC2905030401D947 primary key nonclustered (SomeText)
   commit tran

現在我在另一個(id)列上創建一個唯一的聚集索引,但順序仍然相同

   create unique clustered index CI__TestPrim__BC29050354394FAA on TestPrimaryKey(id)

現在我從表中刪除聚集索引

   drop index CI__TestPrim__BC29050354394FAA on TestPrimaryKey

但是現在排序從“name”列更改為“id”列。我需要知道為什麼會發生這種情況,並且如果表具有非聚集主鍵和聚集索引列,則排序將基於主鍵列、聚集索引列或兩者。

*除非您使用ORDER BY子句明確聲明所需的順序,否則您不能保證數據在響應查詢時呈現的順序。*如果沒有ORDER BY子句,引擎可以自由地以它當時認為最方便的任何順序向您呈現數據,這可能意味著您之前執行的同一查詢的不同順序。

如果存在聚集索引,則數據頁與行按此順序儲存,但這並不能保證它們將按此順序進行處理(如果沒有連接或排序子句,但沒有顯式排序請求將輸出的訂單行正式“未定義”)。

如果沒有聚集索引,則行以無序方式儲存在數據頁中(這稱為“堆表”)。這可能最初與插入數據的順序相同,但一旦刪除和更新開始發生,這絕對不是真的。

如果您想閱讀一些理論查找“集合理論”,關係數據庫所基於的。數學集本質上是無序的,這意味著關係數據庫中的任何東西都應該預設被認為是無序的。

關於非聚集主鍵:這些根本不影響儲存的行數據的順序。它們對您的數據模型有額外的意義,但實際上並沒有做任何具有“唯一”屬性集的非聚集索引會做的事情。同樣,聚集的主鍵只是內部的聚集唯一索引,對您的數據模型具有額外的意義。

**tl;dr:**如果需要以特定方式對數據進行排序,則必須ORDER BY在子句中直接指定該順序。

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