詳解人大金倉數據庫的垂直分區V3.0
1、概述
對一個大問題進行劃分處理是計算機領域常見的手段。在數據庫應用中,對于一個大表,既可以選擇進行水平分區,也可以選擇進行垂直分區。水平分區在主流的數據庫產品中都得到了實現,垂直分區一般要靠數據庫設計人員自行實現(將一個表劃分為多個表)。金倉數據庫V6在數據庫內核中實現了表的垂直分區,它可以簡化數據庫設計人員的工作,并為應用程序提供透明的SQL訪問。
使用垂直分區主要利用了應用對表中字段訪問的如下特性:
(1)字段訪問頻率的不均勻性:即某些字段訪問特別頻繁,其他字段則訪問的較少。可以參考80/20原則。
(2)應用對字段訪問的聚集性:即應用中的查詢傾向于一起訪問某些字段,如a、b、c三列總是一起訪問;d、e兩列總是一起訪問。可以參考局部性原理。
(3)字段訪問順序的依賴性:即應用中的查詢按照某個特定的順序訪問字段,例如訪問d、e字段前總是先訪問a、b、c字段。
在應用對表的訪問滿足以上特性之一時,使用垂直分區可以使訪問/修改這些列的查詢不再需要訪問/修改其他無關列,從而減少物理I/O。
本文給出了一種根據“應用的訪問模式”確定如何對表進行垂直分區(即確定分區表中字段)的思路,并且以一個應用為例。
2、金倉數據庫V6中垂直分區實現方法
金倉數據庫V6支持基于主碼連接的垂直分區,語法如下:
- CREATE TABLE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] [SchemaName.]TableName
- (
- { ColumnName <DataType> [IDENTITY [(Seed, Increment)]]
- [ DEFAULT { NULL | USER | <Expression> } ] [ <ColumnConstraint> ]
- | [ <TableConstraint> ]
- } [, ...n ]
- ) [ <VerticalPartitions> ]
- [TABLESPACE TablespaceName]
- <VerticalPartitions> ::= PARTITION BY COLUMN
- ( [PartitionName]
- ({ ColumnName [, ...n ])
- [TABLESPACE TablespaceName] ) [, ...n ]
垂直分區是按列進行分區,即把一條記錄分開多個地方保存,每個分區的行數相同,列順序與PARTITION子句中的順序。
包括存放沒指定的列的分區,分區數目必須大于等于二,各分區表間允許字段重復,但不能完全重復。
垂直分區基表必須有主碼字段,如果分區沒有指定主碼字段,將在分區中加入基表中的主碼字段。
分區表不能有基表字段之外的字段,表中有但分區表沒指定的字段默認放入一個新的分區表。
主碼字段和重復字段不能指定為IDENTITY。
如果沒有指定分區名,系統會自動建立分區名,分區的命名規則為基表名_VP_[1…N]。分區和基表在同一命名空間。
如果沒有指定表空間,缺省存放到分區基表所在的表空間中。
不支持建立跨分區的表級約束。
例子:
- CREATE TABLE base (
- col1 INT, col2 INT, col3 INT, col4 INT, col5 CHAR(100),
- PRIMARY KEY(col1, col2)
- )
- PARTITION BY COLUMN (P1(col1, col2, col3, col4), P2(col5));
將會創建名為BASE的基表和P1、P2兩個分區表。P1和P2的結構如圖所示,兩個分區都包含元組控制信息(元組頭)、各分區的分區列和作為連接索引的主碼列col1和col2。
3、分區方案的選擇
在決定如何分區選擇時首先要了解應用的場景,然后考慮分區對I/O的影響:
了解應用場景(可以在應用開發過程中進行)
獲得應用中包含的全部查詢;
記錄查詢的順序;
標記查詢執行的次數(或者是百分比);
記錄查詢平均訪問的元組數;
看是否有滿足使用垂直分區的場景
將查詢按照涉及的表分組(涉及多個表的出現在多個組中);
對每一組查詢,做一個表格,表格的列是該組查詢涉及的表的列和列長度,表格的行是查詢;
對于該組每一個查詢,標記該查詢涉及的列;
結合查詢的頻率和訪問元組數粗略查看是否有滿足使用垂直分區的場景;
計算I/O量獲得分區方法
在滿足場景的組中選擇幾個分區方案,包括分區的類型和列的組合。
根據分區類型計算各分區的元組I/O量。
注意盡可能考慮訪問模式,即查詢執行順序帶來的物理I/O差別。可能帶來的差別有:
1)去掉重復計算IO。例如一個涉及分區P1的查詢后會接著執行一條更新該分區的語句,則更新語句的讀就不會是物理讀。
2)考慮命中率問題。不同分區的頁面命中率需要根據分區的訪問頻率進行估計。
計算不分區方案和每個分區方案的I/O量,I/O量為查詢數*元組數*該分區元組I/O量。
比較選擇I/O量最小的方案。
驗證分區帶來的I/O減少
可能會有實際情況與計算不符的情況發生,因為計算中的I/O量是邏輯I/O量而不是準確的物理I/O,實際測試每種方案,收集統計信息(每張表的讀寫信息、頁面的命中率),根據實際值調整方案。
4、實例:TPC-C的垂直分區選擇
TPC-C是一個典型的OLTP類型的負載。TPC-C測試中共有9張表,包括c_warehouse、c_customer、c_district、c_stock、c_order、c_order_line、c_item、c_history和c_new_order;另外,共有5種事務場景:new order、payment、order-status、delivery和stock-level,其中order-status和stock-level是純查詢事務,其它是以更新為主的事務。
分析5種事務包含的查詢,除去c_warehouse、c_distric表等小表,以及更新較多的大表,如c_order和c_order_line,我們可以知道在c_stock表和c_customer表上進行垂直劃分可以帶來較大效率的提升。我們可以根據實際待測試的環境,按照前面描述的原則進行垂直劃分方案的設計、測試和驗證。