索引的正確「打開姿式」

摘要:本文章先描述了經常使用的索引,並針對B-tree和Psort兩種索引具體介紹,下面給出索引的利與弊。除了索引,還介紹了分區、PCK等其餘查詢提速的手段。最後給出各類索引和調優手段的使用場景。

本文分享自華爲雲社區《DWS 索引的正確「打開姿式」》,原文做者:hoholy 。數據庫

索引能幹什麼呢,一言以蔽之:查詢加速。常見的索引有下面幾種:數據結構

1. 經常使用索引介紹

1.1 B-btree索引

B-tree存儲結構示意以下:oop

  • B-tree是平衡樹,有序存儲索引KEY值和TID;
  • 對於索引上的過濾條件,經過KEY快速找到對應的葉子節點,而後再經過TID找到實際記錄;
  • 索引中的數據以非遞減的順序存儲(頁之間以及頁內都是這種順序),同級的數據頁由雙向鏈表鏈接;
  • 支持單列索引和複合(多列)索引,多列複合索引適用於多列組合查詢,B-tree索引對於查詢條件的順序有要求;
  • B-tree索引能夠處理等值和範圍查詢;
  • 索引頁面不存儲事務信息;

在數據庫裏面舉個例子,如何建立B-tree索引:性能

1.2 Psort索引

Psort索引數據結構示意以下圖所示:優化

  • Psort索引自己是個列存表,包含索引列和tid,在索引列上局部排序,利用MIN/MAX塊過濾加速TID獲取;
  • Psort索引自己有可見性,但刪除、更新數據不會做用到Psort索引;
  • Psort索引更適合作範圍過濾,點查詢速度較差;
  • 批量導入場景下有效,對於單條導入無效;

橫向對比B-tree、Psort以下:url

1.3 特殊索引

  • 表達式索引

好比對於查詢「select * from test1 where lower(col1) = ‘value’;」能夠創建在Lower表達式之上的索引「create index on test1(lower(col1));」,後續對於相似在lower(col1)表達式上的過濾條件,就能夠直接使用這個索引加速,對於其餘表達式該索引不會對查詢生效。但須要注意的是:索引表達式的維護代價較爲昂貴,由於在每個行被插入或更新時都得爲它從新計算相應的表達式。spa

  • 部分索引

好比建立一個部分索引「create index idx2 on test1(ip) where not (ip > ’10.185.178.100’ and ip < ’10.185.178.200’);」,使用該縮影加速的典型查詢是這樣「select * from test1 where ip = ’10.185.178.150’」,可是對於查詢「select * from test1 where ip = ’10.185.178.50’」就不能使用該索引。部分索引用來減小索引的大小,排除掉查詢不感興趣的數據,同時能夠加速索引的檢索效率..net

  • 惟一索引

(1)只有B-tree索引支持惟一索引;3d

(2)當一個索引被聲明爲惟一時,索引中不容許多個錶行具備相同的索引值;日誌

(3)空值被視爲不相同,一個多列惟一索引將會拒絕在全部索引列上具備相同組合值的錶行;

(4)對於主鍵列會自動建立一個惟一索引;

(5)惟一性檢查會影響索引插入性能;

1.4 索引的利與弊

索引的優勢以下:

  • 點查詢提速顯著,直接定位到須要的位置,減小無效IO;
  • 多條件組合查詢,過濾大量數據,縮小掃描範圍;
  • 利用倒排索引加速全文檢索;
  • 利用等值條件索引查詢速度快的優點,結合nestloop提升多表join效率;
  • 提供主鍵和惟一性約束,知足業務須要;
  • 利用btree索引自然有序的特色,優化查詢計劃;

索引的缺點以下:

  • 索引頁面佔用額外空間,致使必定的磁盤膨脹;
  • 每次數據導入同時須要更新索引,影響導入性能;
  • 索引頁面沒有可見性,存在垃圾數據,須要按期清理;
  • 索引掃描性能並不老是比順序掃描性能更好,一旦優化器判斷有誤,可能致使查詢性能反向劣化;
  • 索引須要記錄XLOG,增長日誌量;
  • 每一個索引至少一個文件,增長備份恢復、擴容等操做的代價;

鑑於索引的使用是一把雙刃劍,建立索引要謹慎,只給有須要的列建立,不能過濾大量數據的條件列不要建立索引。除了索引能夠優化查詢效率,存儲層還有沒有其餘優化手段呢?下面給你們再介紹幾種DWS查詢提速的手段。

2. DWS查詢提速

2.1 分區

分區是最經常使用的提速手段之一,並且效果很好,推薦你們結合場景多多使用。

  • 目前支持的分區是range分區,分區支持merge、split、exchange等操做;
  • 在時間維度或者空間維度等具備必定數據規律的列上建立分區,分區列上的過濾條件會先作分區剪枝,減小物理掃描量;
  • 相比較索引,分區直接把原始數據物理劃分,一旦分區剪枝生效,會極大的減小IO;
  • 使用分區和使用索引並不衝突,能夠給分區建立索引;

使用分區的注意事項以下:

  • 分區對於導入的影響是增長內存使用(內存不足時會下盤),但不產生額外的磁盤佔用;
  • 使用分區必定要注意分區列的選擇和分區數量的控制,分區過多會致使小文件問題,分區數量建議最多不超過1600個;
  • 分區剪枝適合範圍查詢,對於點查詢效率提高有限;

下面舉個例子,分別建立一樣數據類型的分區表和非分區表,導入相同的數據640萬條,用一樣的查詢會看到分區剪枝對性能提升了7倍多,準備數據:

分區和非分區查詢耗時對比,其中test1是分區表,test2是非分區表,test1的查詢scan耗時6ms,test2的查詢scan耗時46ms,差距7倍還多:

2.2 PCK(partial cluster key)

PCK的本質就是經過排序提高查詢過濾的效率,建立表時指定PCK列,該列上的數據會局部排序,有序的數據帶來更好的數據聚簇性,每一個數據塊的min/max等稀疏索引就能更好的發揮做用,粗過濾掉大量的數據,提高IO效率,默認狀況下420萬行數據局部排序。

注意事項以下:

  • 只有列存表支持PCK,局部排序對每次導入的批量數據生效,不會作全排序;
  • PCK更適用於範圍查詢,點查場景下配套使用PCK和索引能夠達到最佳效果;
  • 帶PCK導入由於排序的緣由會使用更多的內存,影響導入速度,須要權衡導入和查詢性能;

舉個例子,對於查詢select * from tab where col > 65,若是不使用PCK,極可能一個CU都沒法過濾掉,但若是使用了PCK,下圖所示的5個CU就能過濾掉一半還多,提高查詢性能至少50%:

再用上面分區的那組數據橫向對比PCK的性能表現:

(1)列存表,非分區,無PCK,scan耗時46ms

(2)列存表,非分區,有PCK,scan耗時1.7ms

(3)列存表,有PCK,再建立btree索引,scan耗時0.1ms

PCK結合索引,能夠將相似這種點查的性能提高100倍以上。

2.3 智能過濾

列存表數據從文件讀出來,到反饋給執行層,中間會智能識別自動多層過濾,對用戶徹底透明,以下圖所示:

3. 索引使用場景推薦

 

點擊關注,第一時間瞭解華爲雲新鮮技術~

相關文章
相關標籤/搜索