1. 程式人生 > >分散式管理:DB2 深度壓縮,第 2 部分

分散式管理:DB2 深度壓縮,第 2 部分

DB2 9.5 改進了深度壓縮技術,進一步節省空間和提高效能

簡介: 在前一篇專欄文章 “DB2 深度壓縮,第 1 部分” 中,我提到企業資料庫的增長速度大約是每年 125%。隨著資料庫的增長,儲存、保護、分佈和利用資料庫中資料的需求也在增長。為了幫助減少不斷增長的資料庫的儲存需求,IBM 在 DB2 9 中引入了深度壓縮技術。在 DB2 9.5 中根據客戶的反饋進一步改進了這種技術。在本文中,我將介紹 DB2 9.5 中新的壓縮特性。
來自 IBM Database Magazine

儘管在建立表時可以為它啟用深度壓縮,但是在表中填充資料之前,無法構建壓縮詞典。在 DB2 9 中,只有兩種構建壓縮詞典的方法:一種方法是對已經啟用壓縮的填充了資料的表進行重組(執行 REORG 命令並指定 KEEPDICTIONARY 或 RESETDICTIONARY 選項);另一種方法是,估算一個填充了資料的表由於使用壓縮能夠獲得多大好處(執行 INSPECT 命令並指定 ROWCOMPESTIMATE 選項)。

只有根據所有相關資料構建壓縮詞典,才能獲得最好的壓縮率。通過表重組(或使用 Inspect 實用程式)構建壓縮詞典,會獲得很高的壓縮率,因為在構建壓縮詞典時使用了表中的每一行。但是,IBM 的測試表明,只分析少量有代表性的資料,也可能獲得良好的壓縮率。(在某些情況下,僅僅分析總行數的 1%,就能夠獲得 45% 的壓縮率。)這一現象構成了新的壓縮特性 Automatic Dictionary Creation(ADC)的基礎。

在 DB2 9.5 中,如果在建立一個表時啟用了壓縮,那麼一旦表中儲存了足夠的資料,ADC 就會自動構建壓縮詞典。ADC 啟動壓縮詞典構建過程的閾值依賴於表的行大小。在通常情況下,當為表分配了 1-2MB 的頁面時,就開始構建詞典。當達到這個閾值時,ADC 會檢查表中包含多少使用者資料;如果資料至少有 700KB,就會構建壓縮詞典。(注意,這些值是在內部設定的,不能修改。)可能觸發 ADC 的操作包括插入、匯入、裝載和跨分割槽重新分佈資料。

與 Inspect 實用程式構建的壓縮詞典一樣,通過 ADC 建立的詞典也儲存在表中現有資料後面。表中原有的記錄並不壓縮,直到執行離線表重組操作,或者更新原有的記錄(在這種情況下,在儲存修改時對修改的每個記錄進行壓縮)。新記錄在新增時進行壓縮。(ADC 的目標之一是,構建壓縮率比較好的壓縮詞典,同時避免在表中儲存大量未壓縮的資料。)圖 1 顯示,在建立時啟用壓縮的表在 ADC 構建壓縮詞典之前、期間和之後的情況。

在為已經填充資料的表啟用壓縮時(把 COMPRESS 屬性設定為 ON),並不自動建立壓縮詞典。相反,在下一次發生表增長操作時,會觸發 ADC 並使用表中開頭的少量記錄構建壓縮詞典。建立詞典之後,對後續的插入、匯入、裝載和重新分佈操作在表中新增的資料進行壓縮;原有的資料仍然不壓縮。

正如您看到的,壓縮詞典的自動建立受到表的壓縮屬性的影響。如果希望禁止 ADC,那麼先不要為表啟用壓縮,直到您已經準備好手工構建壓縮詞典並壓縮資料。另一方面,如果希望利用 ADC,那麼要記住,與通過離線表重組建立的壓縮詞典相比,ADC 產生的詞典的壓縮率可能不太好。另外,因為在構建壓縮詞典時表仍然線上,在達到閾值並觸發 ADC 時,觸發 ADC 的事務的效能可能會受影響。

DB2 9.5 中的另一個重要變化是,改變了在啟用深度壓縮的表上執行裝載操作的方式。在 DB2 9 中,如果已經為表建立了壓縮詞典,那麼 Load 實用程式在裝載資料時用這個詞典壓縮資料。但是,如果還沒有壓縮詞典,那麼 Load 實用程式並不在裝載操作過程中建立詞典。在 DB2 9.5 中,如果裝載啟用壓縮的表並執行 LOAD REPLACE 操作,Load 實用程式可以構建壓縮詞典。啟動這種操作的方法是執行 LOAD 並指定 REPLACE KEEPDICTIONARY 或 REPLACE RESETDICTIONARY 選項。(如果裝載的表啟用了壓縮,而且達到了觸發 ADC 的資料量,那麼 LOAD INSERT 操作也可以導致建立壓縮詞典。)

如果執行帶 REPLACE KEEPDICTIONARY 或 REPLACE RESETDICTIONARY 選項的 LOAD 命令,而壓縮詞典不存在,就會建立一個新詞典。如果使用 KEEPDICTIONARY 選項,那麼構建壓縮詞典所需的資料量由 ADC 的策略決定。因此,會在表中儲存一些未壓縮的資料;建立詞典之後,使用新詞典壓縮裝載的其他資料。但是,如果指定 RESETDICTIONARY 選項,那麼構建詞典所需的資料量不由 ADC 的策略決定,裝載一行之後就可以構建壓縮詞典。

如果執行帶 REPLACE KEEPDICTIONARY 或 REPLACE RESETDICTIONARY 選項的 LOAD 命令,而壓縮詞典已經存在,那麼將重新建立現有的詞典(RESETDICTIONARY)或按原樣保留它(KEEPDICTIONARY),並用現有詞典或新詞典壓縮表中的資料。

如果希望在執行裝載操作的同時為啟用壓縮的 EMPLOYEE 表建立新的壓縮詞典,應該執行清單 1 中的命令。

                
LOAD FROM datafile.del OF DEL REPLACE RESETDICTIONARY INTO employee

在執行這個命令時,如果 EMPLOYEE 表的壓縮詞典不存在,DATAFILE.DEL 檔案中的一些記錄會不經壓縮裝載到 EMPLOYEE 表中。裝載了 1-2MB 的資料之後,ADC 使用這些資料構建壓縮詞典;然後使用這個壓縮詞典壓縮餘下的記錄並寫入表中。

為了幫助評估深度壓縮對錶的效果,DB2 9.5 中還引入了 ADMINTABCOMPRESSINFO 管理檢視和 ADMIN_GET_TAB_COMPRESS_INFO 表函式。表 1 給出 ADMINTABCOMPRESSINFO 管理檢視的結構。

ADMIN_GET_TAB_COMPRESS_INFO 表函式為 ADMINTABCOMPRESSINFO 管理檢視提供一個程式設計介面,可以在 SQL 查詢中嵌入對這個函式的呼叫。這個函式的語法是:

ADMIN_GET_TAB_COMPRESS_INFO (TableSchema, TableName, ExecMode)

列名 資料型別 說明
TABSCHEMA VARCHAR(128) 模式名
TABNAME VARCHAR(128) 表名
DBPARTITIONNUM SMALLINT 資料庫分割槽號
DATA_PARTITION_ID INTEGER 資料分割槽號
COMPRESS_ATTR CHAR(1) 表的 COMPRESS 屬性的狀態,可以是以下值之一:
‘Y’ 表示 Row compression 設定為 YES
‘N’ 表示 Row compression 設定為 NO
DICT_BUILDER VARCHAR(30) 構建壓縮詞典採用的程式碼路徑,可以是以下值之一:
‹NOT BUILT› 表示沒有詞典
‹INSPECT› 表示 INSPECT ROWCOMPESTIMATE
‹LOAD› 表示 LOAD INSERT/REPLACE
‹REDISTRIBUTE› 表示 REDISTRIBUTE
‹REORG› 表示 REORG RESETDICTIONARY
‹TABLE GROWTH› 表示 INSERT、IMPORT(使用 INSERT 的 IMPORT)或者導致 DB2 把更新的記錄放在新頁面上的更新操作
DICT_BUILD_TIMESTAMP TIMESTAMP 構建壓縮詞典的日期和時間(如果沒有詞典,時間戳就是 NULL。)
COMPRESS_DICT_SIZE BIGINT 壓縮詞典的大小,以位元組為單位。
EXPAND_DICT_SIZE BIGINT 擴充套件詞典的大小,以位元組為單位。
ROWS_SAMPLED INTEGER 構建詞典時使用的記錄數。對於帶著壓縮詞典遷移的表,這個列的值是 NULL。
PAGES_SAVED_PERCENT SMALLINT 通過壓縮節省的頁面的百分比。這一資訊只基於取樣緩衝區中的記錄資料。對於帶著壓縮詞典遷移的表,這個列的值是 NULL。
BYTES_SAVED_PERCENT SMALLINT 通過壓縮節省的位元組的百分比。這一資訊只基於取樣緩衝區中的記錄資料。對於帶著壓縮詞典遷移的表,這個列的值是 NULL。
AVG_COMPRESS_REC_LENGTH SMALLINT 構建詞典時使用的記錄壓縮後的平均長度。對於帶著壓縮詞典遷移的表,這個列的值是 NULL。

其中:

  • TableSchema 指定壓縮資訊所針對的表所在的模式。
  • TableName 指定壓縮資訊所針對的表。
  • ExecMode 指定在執行這個函式時使用的模式。如果這個引數設定為 REPORT(預設值),就會獲取現有的壓縮統計資料。如果這個引數設定為 ESTIMATE,就會根據指定的表中的當前資料生成新的壓縮統計資料;返回的結果反映瞭如果馬上對這個表進行壓縮,將產生的壓縮效果。

例如,如果希望獲取並顯示在壓縮 PAYROLL.STAFF 表時生成的壓縮統計資料,應該執行下面這樣的查詢:

                
SELECT * FROM TABLE(SYSPROC.ADMIN_GET_TAB_COMPRESS_INFO
(‘payroll’, ‘staff’, ‘REPORT’)) AS comp_info;

另一方面,如果希望使用表中當前儲存的資料估計並顯示 PAYROLL.STAFF 表的壓縮統計資料,應該執行下面這樣的查詢:

                
SELECT * FROM TABLE(SYSPROC.ADMIN_GET_TAB_COMPRESS_INFO
(‘payroll’, ‘staff’, ‘ESTIMATE’)) AS comp_info;

第一個查詢報告執行的最後一次壓縮操作的效果;第二個查詢可以指出,通過生成新的壓縮詞典並重新壓縮資料,是否可以改進壓縮的效果。資料會隨著時間變化,所以應該定期執行這兩個查詢,瞭解壓縮的效果。

從 DB2 9.5 開始,小於等於 32KB 的 XML 文件可以儲存在基表的行中,而不需要使用預設的 XML 儲存物件。(更大的文件必須儲存在預設的 XML 儲存物件中。)如果您主要操作小的 XML 文件,那麼以“內聯”方式儲存它們會顯著提高效能。這是因為對直接儲存在基錶行中的 XML 文件進行查詢、插入、更新或刪除所需的 I/O 操作更少。

內聯儲存 XML 文件的另一個好處是,文件本身可以受益於深度壓縮。這是因為深度壓縮在基表上執行,而“內聯的”XML 文件儲存在基錶行中。因為在建立壓縮詞典時會在給定列中尋找重複出現的子字串,所以如果 XML 文件有許多相似的內容,就非常適合進行壓縮,這會減少所需的儲存空間並提高 I/O 效率。

DB2 9 中引入的深度壓縮有助於減少儲存表資料所需的空間。經過壓縮之後,可以在一個頁面中儲存更多的行,所以在有 I/O 瓶頸的系統上,深度壓縮還可以提高查詢效能(在有 CPU 瓶頸的系統不一定有這種效果)。DB2 9.5 對深度壓縮做了一系列改進,使我們能夠更輕鬆地為新表實現壓縮和評估壓縮對錶的效果。DB2 9.5 還允許在批量裝載大量資料時使用壓縮。由於資料庫以每年 125% 的速度增長,在未來的 DB2 版本中很可能會提供效果更好的深度壓縮功能。

感謝 IBM 多倫多實驗室的 Data Management Services 經理 Bill Minor,他向我提供了關於 DB2 9.5 中新的深度壓縮特性的詳細資訊,並審閱了本文。