在進行調優表實踐之前,需要先了解下表結構設計相關的內容。因為進行數據庫設計時,表設計上的一些關鍵項將嚴重影響后續整庫的查詢性能。表設計對數據存儲也有影響:好的表設計能夠減少I/O操作及最小化內存使用,進而提升查詢性能。
本小節介紹如何設計DWS表結構(包括選擇表存儲方式、壓縮級別、分布方式、分布列以及使用分區表和局部聚簇等),從而實現表性能的優化。
選擇存儲方式
表的存儲模型選擇是表定義的第一步。業務屬性是表的存儲模型的決定性因素,根據下表選擇適合當前業務的存儲模型。
一般情況下,如果表的字段比較多(大寬表),查詢中涉及到的列不多的情況下,適合列存儲。如果表的字段個數比較少,查詢大部分字段,那么選擇行存儲比較好。
| 存儲模型 | 適用場景 |
|---|---|
| 行存 | 點查詢(返回記錄少,基于索引的簡單查詢)。 增刪改比較多的場景。 |
| 列存 | 統計分析類查詢(group , join多的場景)。 |
表的行/列存儲通過表定義的orientation屬性定義。當指定orientation屬性為row時,表為行存儲;當指定orientation屬性為column時,表為列存儲;如果不指定,默認為行存儲。
使用表壓縮
表壓縮可以在創建表時開啟,壓縮表能夠使表中的數據以壓縮格式存儲,意味著占用相對少的內存。
對于I/O讀寫量大,CPU富足(計算相對小)的場景,選擇高壓縮比;反之選擇低壓縮比。建議依據此原則進行不同壓縮下的測試和對比,以選擇符合自身業務情況的最優壓縮比。壓縮比通過COMPRESSION參數指定,其支持的取值如下:
- 列存表為:YES/NO/LOW/MIDDLE/HIGH,默認值為LOW。
- 行存表為:YES/NO,默認值為NO。(行存表壓縮功能暫未商用,如需使用請聯系技術支持工程師)
各壓縮級別所適用的業務場景說明如下:
| 壓縮級別 | 所適用的業務場景 |
|---|---|
| 低級別壓縮 | 系統CPU使用率高,存儲磁盤空間充足。 |
| 中度壓縮 | 系統CPU使用率適中,但存儲磁盤空間不是特別充足。 |
| 高級別壓縮 | 系統CPU使用率低,磁盤空間不充裕。 |
選擇分布方式
DWS支持的分布方式有復制表(Replication)、哈希表(Hash)和輪詢表(Roundrobin)。

說明輪詢表(Roundrobin)8.1.2及以上集群版支持。
| 策略 | 描述 | 適用場景 | 優勢與劣勢 |
|---|---|---|---|
| 復制表(Replication) | 集群中每一個DN實例上都有一份全量表數據。 | 小表、維度表。 | Replication優點是每個DN上都有此表的全量數據,在join操作中可以避免數據重分布操作,從而減小網絡開銷,同時減少了plan segment(每個plan segment都會起對應的線程) Replication缺點是每個DN都保留了表的完整數據,造成數據的冗余。一般情況下只有較小的維度表才會定義為Replication表。 |
| 哈希表(Hash) | 表數據通過hash方式散列到集群中的所有DN實例上。 | 數據量較大的事實表。 | 在讀/寫數據時可以利用各個節點的IO資源,大大提升表的讀/寫速度。 一般情況下大表(1000000條記錄以上)定義為Hash表。 |
| 輪詢表(Roundrobin) | 表的每一行被輪番地發送給各個DN,數據會被均勻地分布在各個DN中。 | 數據量較大的事實表,且使用Hash分布時找不到合適的分布列。 | Roundrobin優點是保證了數據不會發生傾斜,從而提高了集群的空間利用率。 Roundrobin缺點是無法像Hash表一樣進行DN本地化優化,查詢性能通常不如Hash表。 一般在大表無法找到合適的分布列時,定義為Roundrobin表,若大表能夠找到合適的分布列,優先選擇性能更好的Hash分布。 |
選擇分布列
采用Hash分布方式,需要為用戶表指定一個分布列(distribute key)。當插入一條記錄時,系統會根據分布列的值進行hash運算后,將數據存儲在對應的DN中。
所以Hash分布列選取至關重要,需要滿足以下原則:
1.列值應比較離散,以便數據能夠均勻分布到各個DN 。例如,考慮選擇表的主鍵為分布列,如在人員信息表中選擇身份證號碼為分布列。
2.在滿足第一條原則的情況下盡量不要選取存在常量filter 的列 。例如,表dwcjk相關的部分查詢中出現dwcjk的列zqdh存在常量的約束(例如zqdh=’000001’),那么就應當盡量不用zqdh做分布列。
3.在滿足前兩條原則的情況,考慮選擇查詢中的連接條件為分布列 ,以便Join任務能夠下推到DN中執行,且減少DN之間的通信數據量。
對于Hash分表策略,如果分布列選擇不當,可能導致數據傾斜,查詢時出現部分DN的I/O短板,從而影響整體查詢性能。因此在采用Hash分表策略之后需對表的數據進行數據傾斜性檢查,以確保數據在各個DN上是均勻分布的。可以使用以下SQL檢查數據傾斜性
select
xc_node_id, count(1)
from tablename
group by xc_node_id
order by xc_node_id desc;
其中xc_node_id對應DN,一般來說,不同DN 的數據量相差5% 以上即可視為傾斜,如果相差10% 以上就必須要調整分布列 。
4.一般不建議用戶新增一列專門用作分布列,尤其不建議用戶新增一列,然后用SEQUENCE的值來填充做為分布列。因為SEQUENCE可能會帶來性能瓶頸和不必要的維護成本。
使用分區表
分區表是把邏輯上的一張表根據某種方案分成幾張物理塊進行存儲。這張邏輯上的表稱之為分區表,物理塊稱之為分區。分區表是一張邏輯表,不存儲數據,數據實際是存儲在分區上的。分區表和普通表相比具有以下優點:
1.改善查詢性能:對分區對象的查詢可以僅搜索自己關心的分區,提高檢索效率。
2.增強可用性:如果分區表的某個分區出現故障,表在其他分區的數據仍然可用。
3.方便維護:如果分區表的某個分區出現故障,需要修復數據,只修復該分區即可。
DWS支持的分區表為范圍分區表和列表分區(列表分區8.1.3集群版本支持)。
使用局部聚簇
局部聚簇(Partial Cluster Key)是列存下的一種技術。這種技術可以通過min/max稀疏索引較快的實現基表掃描的filter過濾。Partial Cluster Key可以指定多列,但是一般不建議超過2列。Partial Cluster Key的選取原則:
1.受基表中的簡單表達式約束。這種約束一般形如col op const,其中col為列名,op為操作符 =、>、>=、<=、<,const為常量值。
2.盡量采用選擇度比較高(過濾掉更多數據)的簡單表達式中的列。
3.盡量把選擇度比較低的約束col放在Partial Cluster Key中的前面。
4.盡量把枚舉類型的列放在Partial Cluster Key中的前面。
選擇數據類型
高效數據類型,主要包括以下三方面:
1.盡量使用執行效率比較高的數據類型
一般來說整型數據運算(包括=、>、<、≧、≦、≠等常規的比較運算,以及group by)的效率比字符串、浮點數要高。比如某客戶場景中對列存表進行點查詢,filter條件在一個numeric列上,執行時間為10+s;修改numeric為int類型之后,執行時間縮短為1.8s左右。
2.盡量使用短字段的數據類型
長度較短的數據類型不僅可以減小數據文件的大小,提升IO性能;同時也可以減小相關計算時的內存消耗,提升計算性能。比如對于整型數據,如果可以用smallint就盡量不用int,如果可以用int就盡量不用bigint。
3.使用一致的數據類型
表關聯列盡量使用相同的數據類型。如果表關聯列數據類型不同,數據庫必須動態地轉化為相同的數據類型進行比較,這種轉換會帶來一定的性能開銷。