測試的版本:SQL Server 2017sql
內存優化表上能夠建立哈希索引(Hash Index)和內存優化非彙集(NONCLUSTERED)索引,這兩種類型的索引也是內存優化的,稱做內存優化索引,和基於硬盤的傳統索引有很大的區別:數組
在建立內存優化表的索引時,第一種方式是在建立表時定義索引,第二種方式是先建立內存優化表,而後經過alter table命令修改表結構,向表中添加索引,而表級別的索引語法以下所示:緩存
<table_index> ::= INDEX index_name { [ NONCLUSTERED ] HASH (column [ ,... n ] ) WITH (BUCKET_COUNT = bucket_count) | [ NONCLUSTERED ] (column [ ASC | DESC ] [ ,... n ] ) [ ON filegroup_name | default ] }
舉個例子,修改表結構,向表中添加哈希索引,在定義索引時必須設置bucket_count的數量:性能優化
ALTER TABLE table_name ADD INDEX idx_hash_index_name HASH (index_key) WITH (BUCKET_COUNT = 64);
內存優化索引適用的場景是:app
1,哈希索引性能優化ide
哈希索引是指SQL Server引擎應用哈希函數F(x),把索引鍵值(Index Key)轉換爲哈希表(哈希索引)。當哈希值相同,而索引鍵不一樣時,稱做產生一個哈希衝突。把哈希值相同的索引鍵連接在一塊兒,組成一個鏈式結構(chain),也稱做衝突鏈。在查找時,須要遍歷衝突鏈來查找數據,所以,衝突鏈變長,會下降哈希查找的性能。函數
哈希衝突是不可避免的,如下兩種狀況,會產生較多的哈希衝突:性能
這兩種狀況致使哈希衝突鏈變長,下降哈希查找的性能,用戶能夠經過下降索引鍵的重複值、增長hashbucket的數量來減小哈希衝突。測試
哈希索引只能點查找(point lookup),而且要求在where子句中應用index key的全部字段、等值條件和與邏輯,例如,哈希索引鍵是colA和colB,在where子句中必須知足:同時出現全部索引鍵、等值條件和與邏輯,也就是:where colA= value1 and colB=value2,只有這樣,才能使用哈希索引進行點查找,不然沒法應用哈希索引。優化
2,內存優化非彙集索引的優化
內存優化非彙集索引的結構是Bw-Tree,在結構上相似於B-Tree結構,具備樹形結構、鍵值是有序的等特色。
從性能上來看,Bw-Tree索引有三個主要特色:
Bw-Tree結構的索引,和普通的B-Tree結構相比,讀寫性能提升,解決了高性能讀和寫不能兼得的問題。
內存非彙集索引相似於B-Tree結構,稱做Bw-Tree。從總體上看,Bw-Tree是按照Page ID組織的頁面映射。
在Bw-Tree結構中,每一個索引Page具備一組有序鍵值(該結構相似於普通的B樹),鍵值是按照大小順序排列的,而且索引中包含層次結構,父級別指向子級別,葉級別指向數據行。
差別是Bw-Tree能夠把多個數據行鏈接在一塊兒,索引結構中的頁面指針是邏輯頁面的ID,這個邏輯頁面的ID其實是頁面映射表的偏移量,該映射表具備每一個頁面的物理地址,經過偏移量找到每一個頁面在內存中實際的物理地址。
在非葉子級別中,父級別的頁面中存儲的鍵值是它指向的子級頁面中的鍵值的最大值,而且每一行還包含該頁面邏輯頁ID(偏移量)。葉級數據頁不只包含鍵值,還包含頁面的物理地址。
Bw-Tree結構大體以下圖所示:有相似B-Tree的樹形結構(存儲的數據和索引)和Mapping Table(存儲邏輯頁面ID和物理地址的映射)。
在內存非彙集索引中,沒有索引頁的就地更新(in-place update),爲了實現該目的,引入了新的更新機制:
Bw-Tree結構解決了B-tree高性能讀和寫不能兼得的問題,可能會存在性能抖動。
哈希索引包含一個由指針構成的數組,數組中的每一個元組叫作一個hash bucket:
哈希索引的結構,以下圖所示,左側是哈希表,右側上一是表數據(Name、City)+時間戳+索引指針,右側中下的兩行是表數據,中間經過Index prt連接爲一個chain。
hash bucket的數量必須在索引定義時指定:
參考文檔: