DB2 性能優化是一件較為復雜的綜合性的工作 , 需要對問題的根源作全方位的探索和思考。同時也需要較深厚的數據庫管理經驗與優化知識。這對於初學者來說可能有些勉為其難。但是在很多情況下,隨著 DB2 數據庫中的數據量的不斷增長或者用戶數的激增,數據庫系統的性能會顯著下降,而此時快速定位性能上的瓶頸則至關重要。下面簡要地介紹一下 DB2 的調優的一些因素和工具,以及一些原理,使初學者對性能優化能夠有一個大致的了解。
DB2 的性能優化可以從三個方面分析:內存,CPU 和 I/O 。
內存因素
在內存方面,主要是考慮緩沖池 (BUFFERPOOL) 的使用。緩沖池是一片用來緩沖從磁盤上讀取的數據和索引的內存區域,這些數據和索引信息在緩沖池中進行運算後最終還要寫回磁盤。緩沖池的頁面大小有四種 (4K,8K,16K,32K),分別對應四種不同頁面大小的表空間。緩沖池的大小決定了能夠從磁盤上緩沖數據的容量大小。當然緩沖池也不是越大越好,緩沖池過大可能會導致連接數據庫的時間過長,因為在連接數據庫時要為數據庫的緩沖池分配內存空間。可以通過計算緩沖池的命中率來評估緩沖池的使用效率:緩沖池命中率 =(1-(( 數據物理讀 + 索引物理讀 )/( 數據邏輯讀 + 索引邏輯讀 ))) *100%,緩沖池命中率越大說明緩沖池的使用效率高。緩沖池命中率太小說明緩沖池太小應當調大。其中的數據物理讀,索引物理讀以及數據邏輯讀和索引邏輯讀都可以從緩沖池的快照中獲取。
在內存方面要考慮的另外幾個重要因素是排序堆 (SORTHEAP),鎖列表 (LOCKLIST), 日志緩沖區 (LOGBUFSZ) 。排序堆在查詢結果帶有排序選項而沒有相關索引對應時將會被使用,排序堆太小會產生排序溢出 (Overflowed), 那些在排序堆中裝不下的排序數據將會溢出到一個臨時表中,這會使性能下降。與 SORTHEAP 參數相關的是 SHEAPTHRES_SHR 和 SHEAPTHRES,SHEAPTHRES_SHR 限制了一個數據庫中共享排序的最大內存,SHEAPTHRES 限制了私有排序的最大內存。 LOCKLIST 指的是一個數據庫中用來存放鎖的內存空間,當這個參數設得過小會導致在鎖用光這部分資源後導致鎖升級(即多個行鎖轉化為一個表鎖來釋放出更多的資源)。這會導致系統的並行性下降,很多應用連接出現掛起,使得系統的性能衰退。所以盡可能調大 LOCKLIST 參數,這裡需要指出 LOCKLIST 指的並不是鎖的個數,而是以數據庫頁為單位的一片內存區域(在 32 位系統中每個鎖需要 96 個字節,鎖上加鎖的話每個鎖則需 48 個字節。在 64 位系統中每個鎖需要 128 個字節,鎖上加鎖的話每個鎖則需 64 個字節)。與 LOCKLIST 參數對應的是 MAXLOCKS 參數,MAXLOCKS 定義的是一個百分數,它指定了一個應用程序所能占用的最大的鎖空間占 LOCKLIST 的比例。日志緩沖區 (LOGBUFSZ) 指的是日志在寫到磁盤以前用於緩沖的一片內存空間,這樣可以減少寫日志帶來的過多的 I/O 。
從版本 9 以後 DB2 推出了一個新特性自調節內存管理器 (STMM: Self Tuning Memory Manager), 這個特性使得很多內存參數如前面所述的 SORTHEAP,LOCKLIST,LOGBUFSZ 等進行自動調節,當數據庫參數 SELF_TUNING_MEM 設為 ON, 這些參數設為 AUTOMATIC 即可以進行自動調整。這樣可以節省很多人工調整的時間。
CPU 因素
關於 CPU 因素首先是考慮 DB2 優化器 (OPTIMIZER) 對訪問計劃 (ACCESS PLAN) 的分析與優化。一般來說,一條 SQL 在執行時首先會被解析,然後進行語義分析,進而重寫 SQL, 優化器會對重寫過的 SQL 進行基於成本的分析最終選擇最有效的訪問計劃。最終生成可執行代碼(執行計劃)來執行這條語句。查詢訪問計劃的工具有很多,既有圖形化工具 Visual Explain,也有命令 db2exfmt 來格式化解釋表 (Explain tables) 中的數據生成 ACCESS PLAN 。還有命令 db2expln 查詢 Access PLAN 。
在 DB2 裡的優化級別分為九級,缺省是第五級,級別越高優化器分析得程度越深。這個級別有數據庫配置參數 DFT_QUERYOPT 決定。並不是級別設得越高性能越好,因為對於一些較為簡單的 SQL 語句,如果優化級別過高那麼花在優化 SQL 上的時間就會過長,而執行時間相對來說很短,有些得不償失。在選擇訪問計劃時,索引掃描的效率往往會比表掃描要高,所以索引的優化也是值得注意的。正確的建立索引會使查詢性能大幅度的提高。
在 DB2 中連接 (JOIN) 分為三種:嵌套循環連接 (nest-loop join), 合並連接 (merge-join), 散列表連接 (hash-join) 。一般來說效率最低的是嵌套循環連接,這種連接采用的是笛卡兒集,進行多次循環遍歷得到結果。而合並連接和散列表連接只進行一次循環遍歷,相對來說效率較高。其中散列表連接可以采用多個等式做為條件而合並連接只能采用單個等式作為條件。但是在有索引掃描的情況下嵌套循環連接效率則更高。當優化級別等於零時,連接只能采用嵌套循環連接, 當優化級別大於等於 1 時,連接可以采用合並連接。當優化級別大於 5 時連接可以采用散列表連接。散列表連接要求 SORTHEAP 比較大,因為要為生成散列表准備空間。
在考慮 CPU 因素時還要考慮 CPUSPEED 這個參數,這個參數標明了 CPU 的運行速度,它會幫助優化器評估最好的訪問計劃。一般來說這個參數設為 -1,優化器將自動計算 CPU 的速度。另外運用多分區的特性可以把一個數據庫分布到多台機器上,這樣可以充分利用多台機器的 CPU 的資源對應用程序的事務進行並行處理,從而提高數據庫的性能。
I/O 因素
關於 I/O 因素要考慮以下幾個方面:首先是磁盤的 I/O, 為了能夠最大化磁盤的 I/O 可以把數據,索引以及日志分別放在不同的硬盤上。因為在一個事務中數據和索引可能需要同時訪問,而在事務提交時,數據和日志要同時寫入磁盤,而且有可能索引也要同步維護,所以將它們放在不同的硬盤上可以使它們的讀寫並行運行,從而不致使磁盤成為瓶頸。同時選擇數據庫管理表空間 (DMS) 要比系統管理表空間 (SMS) 性能要好,因為讀寫 SMS 需要經過操作系統的 cache 再到緩沖池,而可以采用裸設備的 DMS 則不需要。但是 DMS 相對 SMS 來說維護起來較麻煩。
其次要考慮的是日志文件的大小,當數據庫在寫事務日志時當一個日志文件寫滿後會轉向另外一個日志文件,這種日志文件的切換會造成操作系統上的開銷。所以應當盡量將日志文件大小(LOGFILSIZ)設得大一些,這樣可以減少日志文件切換的次數。但是日志文件過大難免會造成一些空間的浪費。
同時也要考慮到隔離級別的因素,在 DB2 中隔離級別分成 4 級:可重復的讀,讀穩定性,游標穩定性和未提交的讀。這四種級別逐個降低。越高的隔離級別越能保證數據完整性,但卻會降低並發性,所以應當綜合權衡後做出決定。隔離級別可以通過如下命令來改變:
CHANGE ISOLATION TO=CS|RR|RS|UR
在連接方面還要考慮到代理和連接的關系,這也會影響到數據庫的並發性,具體信息可以參考資源部分。
最後要考慮的還是關於多分區的特性。在多分區數據庫中,一個請求首先傳到協調分區,然後由協調分區將請求細分成多個部分發送到其他分區,這樣數據可以在各個分區進行並行讀寫,實現 I/O 最大化。
性能優化相關工具
在 DB2 中有很多和性能優化相關的工具和命令,下面簡單地介紹幾種:
還有一些 DB2 中其他的文件可以用來分析性能問題,比如說診斷日志,追蹤文件等。一些第三方的工具也可供參考,如“ tivoli monitor for db2 ”, QUEST 等等。
其他性能因素
XML 的優化: 在 DB2 V9 以後引入了純 XML 的數據類型,這是一種層次型數據類型。這和傳統的關系型數據類型不一樣,在 V9 以前 DB2 存儲 XML 數據使用 CLOB 數據類型,應用程序在存取 XML 數據的時候必須先要解析 XML 再使用其數據。而在純 XML 類型中,可以直接讀取其中的元素,這樣性能會有較大的提高。另外針對純 XML 還有 XML 的索引,也會增大存取的性能。
操作系統: 數據庫存在於操作系統之上,操作系統的性能將直接影響到數據庫的運行效率,因此優化操作系統也是優化數據庫的一個重要過程。在操作系統級別上可以對內存進行優化,比如說對系統共享內存,信號量以及虛擬內存的設置等等都可以影響到數據庫的性能。同時在磁盤的分布上也會影響到數據庫 I/O 效率。
網絡: 網絡將會影響到數據庫的 I/O 性能,當數據通過網絡在客戶端和服務器端進行傳送時,網絡上出現瓶頸會導致數據庫 I/O 性能顯著下降。所以選擇優良的網絡設備以及配置良好的網絡環境對數據庫性能相當重要。同時也要考慮到防火牆的因素,有時防火牆會阻擋來自某些 IP 的數據包。