3、索引優化(2)彙集索引

1、彙集索引的概念jquery

   彙集索引根據數據行的鍵值在表或視圖中排序和存儲這些數據行。 索引定義中包含彙集索引列。 每一個表只能有一個彙集索引,由於數據行自己只能按一個順序排序。數據庫

  只有當表包含彙集索引時,表中的數據行才按排序順序存儲。 若是表具備彙集索引,則該表稱爲彙集表。 若是表沒有彙集索引,則其數據行存儲在一個稱爲堆的無序結構中。ide

  下圖是彙集索引的示意圖。與前文所述的非彙集索引相比,彙集索引在結構上的最大特色是:索引的葉級就是數據頁。測試

 

 

 

2、實驗[三C]:(非惟一)彙集索引ui

1. 建立非彙集索引 spa

  繼續使用前一篇文章的測試專用表,首先刪除原有的非彙集索引,而後建立一個彙集索引。指針

DROP INDEX IX_person1_UserID ON person1orm

CREATE CLUSTERED INDEX IX_person1_UserID ON person1 (UserID)xml

 

2. 查看索引的空間分配blog

DBCC SHOWCONTIG ('person1') WITH ALL_INDEXES

  結果以下:

DBCC SHOWCONTIG 正在掃描 'person1' 表...
表: 'person1' (245575913);索引 ID: 1,數據庫 ID: 8
已執行 TABLE 級別的掃描。
- 掃描頁數................................: 4009
- 掃描區數..............................: 502
- 區切換次數..............................: 501
- 每一個區的平均頁數........................: 8.0
- 掃描密度 [最佳計數:實際計數].......: 100.00% [502:502]
- 邏輯掃描碎片 ..................: 0.37%
- 區掃描碎片 ..................: 0.80%
- 每頁的平都可用字節數.....................: 44.2
- 平均頁密度(滿).....................: 99.45%
DBCC 執行完畢。若是 DBCC 輸出了錯誤信息,請與系統管理員聯繫。

 

  將上述結果與前文的非彙集索引相比,很明顯可見數據頁與索引頁合爲一體(索引ID=1)。注意,此處自動增長了9個頁,後文將會說明緣由。

 

3. 查看索引的層次

SELECT index_depth, index_level, record_count, page_count,
min_record_size_in_bytes as 'MinLen',
max_record_size_in_bytes as 'MaxLen',
avg_record_size_in_bytes as 'AvgLen',
convert(decimal(6,2),avg_page_space_used_in_percent) as 'PageDensity'
FROM sys.dm_db_index_physical_stats
  (8, OBJECT_ID('person1'),1,NULL,'DETAILED')

  結果以下:

Index

_depth

Index

_level

Record

_count

Page

_count

MinLen

MaxLen

AvgLen

PageDensity

3

0

80000

4009

399

407

401.498

99.45

3

1

4009

10

14

22

16.632

92.26

3

2

10

1

14

22

18

2.45

 

  根據上表的數據,能夠看到該索引共有3層。最底層 level=0 是葉級,它有4009個頁面,這個葉級實際上就是包含80000行數據的數據頁。非葉級共有2層,其中level=1 是中間級,它有10個頁面,保存了4009個指針分別指向葉級的4009頁;level=2 是根,它只有1個頁面,保存了10個指針分別指向中間級的10個索引頁。 

  中間級索引的行長度爲14~22個字節,根級索引的行長度也爲14~22 個字節。詳細的計算方法,見《估計彙集索引的大小》http://technet.microsoft.com/zh-cn/library/ms178085.aspx

 

4. 總結

  索引的層次與頁面結構以下圖:

 

 

 

3、實驗[三D]:(惟一)彙集索引

  彙集索引中的數據便可以惟一,也能夠不惟一,取決於定義這個索引時的 UNIQUE 設置。

  若是未使用 UNIQUE 屬性建立彙集索引,SQL Server 將向表自動添加一個 4 字節 uniqueifier 列,使每一個鍵惟一。此列和列值僅供內部使用,用戶不能查看或訪問。

1. 建立測試用的表

  建立一個新的表,並添加80000行記錄。

create table person3 (UserID int not null,pwd char(20),OtherInfo char(360),modifydate datetime)
declare @i int
set @i=0
while @i<80000
begin
  insert into person3 
  select @i,cast(floor(rand()*100000) as varchar(10)),
  cast(floor(rand()*100000) as char(50)), GETDATE()
  set @i=@i+1
end

 

2. 檢查頁數量

  使用DBCC SHOWCONTIG,查得該表的頁的數量爲4000頁。

 

3. 建立惟一彙集索引

CREATE UNIQUE CLUSTERED  INDEX  IX_person3_UserID  
    ON person3 (UserID) 

 

4. 檢查頁的數量

  再次使用DBCC SHOWCONTIG,查得該表的頁的數量仍然爲4000頁。

 

5. 查看索引的層次

SELECT index_depth, index_level, record_count, page_count,
min_record_size_in_bytes as 'MinLen',
max_record_size_in_bytes as 'MaxLen',
avg_record_size_in_bytes as 'AvgLen',
convert(decimal(6,2),avg_page_space_used_in_percent) as 'PageDensity'
FROM sys.dm_db_index_physical_stats
  (8, OBJECT_ID('person3'),1,NULL,'DETAILED')

  結果爲:

Index

_depth

Index

_level

Record

_count

Page

_count

MinLen

MaxLen

AvgLen

PageDensity

3

0

80000

4000

399

399

399

99.06

3

1

4000

7

11

11

11

91.75

3

2

7

1

11

11

11

1.10

 

  與前一個實驗中的不帶UNIQUE 的彙集索引相比,因爲不須要建立一個 4 字節的uniqueifier 列,所以惟一彙集索引的數據行仍然是原來的固定長度,數據頁的數量也不會增長。並且,因爲數據行的惟一性,非葉級索引的寬度也減少到11個字節,其中4個字節用於定義彙集索引的 int 列(UserID列),6個字節用於頁指針,1個字節用於行的系統開銷。

 

6. 總結

  索引的層次與頁面結構以下圖所示:

 

 

4、彙集索引與約束

1. 主鍵的概念

  主鍵,也稱主關鍵字(Primary Key),是表中的一個或多個列,它的值用於唯一地標識表中的某一條記錄。在兩個表的關係中,主鍵用來在一個表中引用來自於另外一個表中的特定記錄。主鍵是一種惟一鍵,是表定義的一部分。

  一個表只能包含一個主鍵約束。若是在其餘列上創建主鍵,則原來的主鍵就會取消。定義主鍵後,在主鍵的左側會顯示一個鑰匙狀的圖標,表示該字段已被設爲主鍵。

  在主鍵約束中定義的全部列都必須定義爲 NOT NULL。 若是沒有指定爲 Null 性,則加入主鍵約束的全部列的爲 Null 性都將設置爲 NOT NULL。

 

2. 主鍵與索引的關係

  建立主鍵將自動建立相應的惟一索引、彙集索引或非彙集索引。例如

ALTER TABLE person 
ADD CONSTRAINT PK_person_UserID PRIMARY KEY CLUSTERED (UserID)

  數據庫在建立主鍵同時,會自動創建一個惟一索引。
  若是這個表以前沒有彙集索引,同時創建主鍵時候沒有強制指定使用非彙集索引,則創建主鍵時候,同時創建一個惟一的彙集索引。例如,下例中將自動建立一個彙集、惟一索引。

create table person (UserID int not null,pwd char(20),modifydate datetime)

ALTER TABLE person 
ADD CONSTRAINT PK_person_UserID PRIMARY KEY (UserID)

 

3. 惟一約束與索引的關係

  惟一約束(UNIQUE CONSTRAINT)與主鍵約束相反,除非顯式指定了彙集索引,不然,默認狀況下將建立惟一的非彙集索引以強制執行惟一約束。

 

4. 約束與索引的主要區別

  主鍵約束和惟一約束的主要目的都是爲了保持數據行的惟一性,不容許有重複的數據行;而彙集索引的主要目的是爲了使數據按照必定的順序進行物理排序以加快查詢的速度,而且容許有重複的數據行。

相關文章
相關標籤/搜索