感謝原博主html
http://yishueitian326.blog.163.com/blog/static/2858637520106695733719/node
性 能是關係到隨需應變型應用程序成功與否的關鍵。當那些應用程序使用 IBM? DB2 Universal Database? 做爲數據存儲時,相當重要的是,從一開始就應該知道有關如何在 DB2 UDB 上取得儘量好的性能的基礎知識。在本文中,我將給出關於調優 DB2 UDB V8 系統的一些比較深刻的建議。ios
我 們將談論這一過程當中自始至終存在的性能問題。您能夠遵循從建立一個新數據庫到運行應用程序這之間的流程。經過本文能夠看到如何使用 DB2 自動配置實用程序來初始配置數據庫管理器和數據庫環境。接着,我將討論建立緩衝池、表空間、表和索引的最佳實踐。另外,您可能還想改變一些重要配置參數的 初始值,以便更好地支持應用程序,所以咱們還將簡介這些配置參數。web
我 們將論述基於監視器(monitor)細節輸出的調優,從而展現如何使用快照監視(snapshot monitoring)幫助調優 SQL、緩衝池和各類不一樣的數據庫管理器以及數據庫配置參數。接着,咱們將進一步研究應用程序發送給 DB2 的 SQL。經過使用 Explain,能夠生成 SQL 採用的訪問計劃(access plan),並尋找能夠進一步優化的機會。咱們將考察 Design Advisor 這樣一個工具,它能夠根據所提供的 SQL 負載推薦出新的索引,或者評估現有的索引。最後,咱們還將討論一些 DB2 SQL 選項。sql
此 外,持續(on-going)維護對於維持最佳性能很是重要。因此咱們將討論一些能夠幫助咱們進行持續維護的實用程序。對於那些正使用 DB2 ESE Database Partitioning Feature (DPF) 的讀者,我會用一節的篇幅談論爲使數據庫高效運行而應該考慮的一些問題。有時候可能會存在某種外在的瓶頸(來自 DB2)而使您沒法達到性能目標,本文列出了一些常見的瓶頸,以及用於監視這些瓶頸的實用程序。最後,本文列出了一些有價值的 IBM 資源,以幫助您發現有價值的 DB2 信息。數據庫
本文是爲那些在 DB2 數據庫管理方面有中級技能的人而寫的。編程
在開始性能調優過程以前,應確保您已經應用了最新的 DB2 修訂包(fix pack)。修訂包經常會帶來性能的提升。咱們要使用 DB2 FixPak 4 做爲本文的基礎。若是您使用的是 FP4 以前的版本,那麼這種環境可能不能提供這裏討論的全部選項。安全
在 進行調優時,最好是有一個關於數據庫使用(即應用程序運行在 DB2 上的工做負載)的可再現場景,這樣就能夠利用這種可再現場景來量身定製調優效果。例如,若是工做負載在不一樣的運行期間所經歷的時間上有 10% 的變化量,那麼就很難知道調優的真正效果如何。此外,若是在兩次運行中各自的工做負載不同,也就難於衡量數據庫管理器和數據庫配置參數所發生的變化。服務器
堅持跟蹤全部的變化。這樣有助於開發調優腳本或者建議,以做爲供其餘 DBA 參考的歷史,同時也有助於防止遵循不良的變化。
在大多數小節的最後,都有一些指向 DB2 v8 HTML Documentation 中相關小節的連接。在線文檔能夠在 http://publib.boulder.ibm.com/infocenter/db2help/index.jsp上找到。
![]() ![]() |
![]()
|
作了下面十件事情,您就幾乎可使數據庫得到最佳性能。一般您會發現,經過大約 10% 的配置變化,就能夠達到最佳性能的 90%。我將在下面適當的小節(在圓括號中標出)中詳細討論其中的每一條:
![]() ![]() |
創 建一個數據庫時,系統會缺省地建立 3 個系統管理存儲(System Managed Storage,SMS) 表空間(SYSCATSPACE、TEMPSPACE1 和 USERSPACE),以及一個 4 MB 的緩衝池(IBMDEFAULTBP),這些表空間和緩衝池的頁面大小都是 4 KB 。根據下面的建議,先刪除 TEMPSPACE1 和 USERSPACE 而後再從新建立它們,一般這是一種可取的作法。幾乎在全部狀況下, SYSCATSPACE 都不須要再做進一步的優化,可是若是將其容器展開到幾個磁盤上,性能上可能會有少許提高。( 稍後討論)。
在 建立數據庫時,您能夠利用自動配置選項來根據環境對數據庫進行最初的配置。當應用程序以編程方式建立 DB2 數據庫時,這樣作很方便,由於能夠將這些選項從應用程序提供給 DB2。在自動配置數據庫時不得不用到的另外一個選項是更強大的 Configuration Advisor GUI,它不但能夠配置數據庫,並且還能夠配置實例。不過,要使用 Configuration Advisor,數據庫必須首先存在。咱們將在 隨後的小節中討論 Configuration Advisor。
在 清單 1中,咱們使用 CREATE DATABASE 命令的自動配置選項在 Windows 中建立了一個數據庫,該數據庫有一個跨越兩個可用磁盤的 SYSCATSPACE。
create database prod1 catalog tablespace managed by system using ('c:\\proddb\\cattbs\\01','d:\\proddb\\cattbs\\02') extentsize 16 prefetchsize 32 autocon圖 using mem_percent 50 workload_type simple num_stmts 10 tpm 20 admin_priority performance num_local_apps 2 num_remote_apps 200 isolation CS bp_resizeable yes apply db and dbm |
表 1顯示了有效的自動配置輸入關鍵字以及值:
關鍵字 | 有效值 | 缺省值 | 描述 |
mem_percent | 1-100 | 25 | 分配給數據庫的物理存儲空間的百分比。若是本服務器(不包括操做系統)上運行有其餘應用程序,那麼將其設爲小於 100 的某個值 |
workload_type | simple, mixed, complex | mixed | simple 型工做負載傾向於 I/O 密集型,而且大多數是事務處理(OLTP),而 complex 型工做負載則傾向於 CPU 密集型,而且大多數是查詢(OLAP/DSS) |
num_stmts | 1-1000000 | 25 | 每一個工做單元包含的語句條數 |
tpm | 1-200000 | 60 | 每分鐘的事務數。 |
admin_priority | performance, recovery, both | both | 優化以得到更好性能(每分鐘更多的事務數)或更好的回覆時間 |
num_local_apps | 0-5000 | 0 | 鏈接的本地應用程序的數目 |
num_remote_apps | 0-5000 | 100 | 鏈接的遠程應用程序的數目 |
isolation | RR, RS, CS, UR | RR | 鏈接到該數據庫的應用程序的隔離級別(Repeatable Read、Read Stability、Cursor Stability 和 Uncommitted Read)。 |
bp_resizeable | yes, no | yes | 是否能夠在線更改緩衝池大小 |
如 果您在建立數據庫的時候已經使用了自動配置,那麼這一步就不是很重要了。Configuration Advisor 是一個 GUI 工具,它容許根據您針對一系列問題給出的回答自動配置數據庫和實例。經過使用這種工具,經常能夠取得至關可觀的性能提高。這個工具能夠從 Control Center 中經過右鍵單擊數據庫並選擇 "Configuration Advisor" 來打開。當您回答完全部問題後,就能夠生成結果,還能夠選擇應用結果。 圖 1展現告終果頁面的屏幕快照:
圖 1. Configuration Advisor Results 屏幕
![]() ![]() |
![]()
|
恰當地定義緩衝池是擁有一個運行良好的系統的關鍵之一。對於 32 位操做系統,知道共享存儲器的界限十分重要,由於這種界限將限制數據庫的緩衝池(即數據庫的全局存儲器),使其不能超出如下界限(64 位系統沒有這樣的界限):
用下面的公式計算近似的數據庫全局存儲器的使用:
buffer pools + dbheap + util_heap_sz + pkgcachesz + aslheapsz + locklist + approx 10% overhead |
若是啓用了 INTRA_PARALLEL,那麼將 sheapthres_shr 的值加到總和中。
對於數據庫中一個表空間所使用的每一種頁面大小,都須要至少一個緩衝池。一般,缺省的 IBMDEFAULTBP 緩衝池是留給系統編目的。爲處理表空間的不一樣頁面大小和行爲,須建立新的緩衝池。
對於初學者,一開始爲每種頁面大小使用一個緩衝池,對於 OLAP/DSS 類型的工做負載更是如此。DB2 在其緩衝池的自我調優方面十分擅長,而且會將常常被訪問的行放入內存,所以一個緩衝池就足夠了。(這一選擇也避免了管理多個緩衝池的複雜性。)
如 果時間容許,而且須要進行改進,那麼您可能但願使用多個緩衝池。其思想是將訪問最頻繁的行放入一個緩衝池中。在那些隨機訪問或者不多訪問的表之間共享一個 緩衝池可能會給緩衝池帶來「污染」,由於有時候要爲一個原本可能不會再去訪問的行消耗空間,甚至可能將常常訪問的行擠出到磁盤上。若是將索引保留在它們自 己的緩衝池中,那麼在索引使用頻繁的時候(例如,索引掃描)還能夠顯著地提升性能。
這與咱們對錶空間的討論是緊密聯繫的,由於要根據表空間中表的行爲來分配緩衝池。若是採用多緩衝池的方法,對於初學者來講使用 4 個緩衝池比較合適:
對於 DMS 只包含 LOB 數據的表空間,能夠爲其分配任何緩衝池,由於 LOB 不佔用緩衝池空間。
千萬不要爲緩衝池分配多於所能提供的內存,不然就會招致代價不菲的 OS 內存分頁(memory paging)。一般來說,若是沒有進行監控,要想知道一開始爲每一個緩衝池分配多少內存是十分困難的。
對於 OLTP 類型的工做負載,一開始將 75% 的可用內存分配給緩衝池比較合適。
對於 OLAP/DSS,經驗法則告訴咱們,應該將 50% 的可用內存分配給一個緩衝池(假設只有一種頁面大小),而將剩下的 50% 分配給 SORTHEAP。
倚 重於預取技術的 OLAP 查詢能夠得益於基於塊的緩衝池。缺省狀況下,全部緩衝池都是基於頁的,這意味着預取操做將把磁盤上相鄰的頁放入到不相鄰的內存中。而若是採用基於塊的緩衝 池,則 DB2 將使用塊 I/O 一次將多個頁讀入緩衝池中,這樣能夠顯著提升順序預取的性能。
一 個基於塊的緩衝池由標準頁區和一個塊區同時組成。CREATE 和 altER BUFFERPOOL SQL 語句的 NUMBLOCKPAGES 參數用於定義塊內存的大小,而 BLOCKSIZE 參數則指定每一個塊的大小,即在一次塊 I/O 中從一個磁盤讀取的頁的數量。
共享相同區段大小的表空間應該成爲一個特定的基於塊的緩衝池的專門用戶。將 BLOCKSIZE 設置爲等於正在使用該緩衝池的表空間的 EXTENT SIZE。
確 定分配多少內存給緩衝區內的塊區要更爲複雜一些。若是要碰到大量的順序預取操做,那麼您極可能會想要更多基於塊的緩衝池。NUMBLOCKPAGES 應該是 BLOCKSIZE 的倍數,而且不能大於緩衝池頁面數量的 98%。先將它設小一點(不大於緩衝池總共大小的 15% 或恰好 15%)。在後面還能夠根據快照監視(snapshot monitoring)對其進行調整。
![]() ![]() |
![]()
|
既然要爲表空間分配緩衝池, 關於緩衝池的上一節就跟涉及表空間的性能問題十分相關。使用 DB2 Control Center 是建立和配置表空間的最容易的方法,也是咱們推薦的方法(右鍵單擊數據庫的 Table Spaces文件夾並選擇 Create...)。
對於系統臨時表空間和系統編目表空間,應該使用 System Managed Storage(SMS), 由於它容許表空間動態地增加和收縮。若是有大量臨時表要刷新到磁盤上(或者是沒有足夠的排序空間,或者是顯式地建立臨時表),則 DMS 會更有效一些。當使用 SMS 時,應該運行實用程序 'db2empfa',這個實用程序將支持多頁文件分配,從而一次一個區段地增加表空間,而不是一次一頁地增加表空間。
對於全部其餘的表空間,應該使用 Database Managed Storage(DMS)。DMS 容許一個表跨越多個表空間(索引、用戶數據和 LOB),這樣就減小了在預取和更新操做時索引、用戶和 LOB 數據之間的爭用,從而縮短了數據訪問的時間。經過使用 DMS raw 甚至還能夠擠出額外的 5-10% 的性能提高。
爲 了建立一個表,必須有一個表空間,其頁面大小應足以容納一行。您能夠選擇使用 四、八、16 或 32 KB 這幾種頁面大小。有時候必須使用較大的頁面大小,以迴避某些數據庫管理器的限制。例如,表空間的最大尺寸與表空間的頁面大小成比例。若是使用 4K 的頁面大小,那麼表空間的大小(每一個分區)最大是 64 GB,若是使用 32K 的頁面大小,那麼最大是 512 GB。
對於執行隨機更新操做的 OLTP 應用程序,採用較小的頁面大小更爲可取,由於這樣消耗的緩衝池中的空間更少。
對 於要一次訪問大量連續行的 OLAP 應用程序,一般使用較大頁面大小效果會更好些,由於這樣能夠減小在讀取特定數量的行時發出的 I/O 請求的數量。較大的頁面大小還容許您減小索引中的層數,由於在一頁中能夠保留更多的行指針。然而,也有例外狀況。若是行長度小於頁面大小的 255 分之 1,則每一頁中都將存在浪費的空間,由於每頁最多隻能有 255 行(對於索引數據頁不適用)。在這種狀況下,採用較小的頁面大小或許更合適一些。
例如,若是要使用 32K 的頁面大小來存儲平均大小爲 100 字節的行,則一個 32 KB 的頁只能存儲 100 * 255 = 25500 byte (24.9 KB)。這意味着每 32 KB 中就有大約 7 KB 要浪費掉。
與緩衝池同樣,一開始應該爲每種頁面大小使用一個緩衝池。對於所使用的每種頁面大小,必須存在一個具備匹配頁面大小的系統臨時表空間(以支持排序和重組)。而後將全部享用匹配頁面大小的表空間指派給具備相同頁面大小的緩衝池。
若是您還關心性能問題,而且有時間投入,那麼可使用 DMS 表空間,而且根據使用狀況來組織表。另外,還要遵循前面給出的關於使用多個緩衝池的建議。
對於每種頁面大小,建立一個:
一開始最好是對於每一個 CPU 分配 6-10 個磁盤給表空間。每一個表空間應該跨越多個磁盤,也就是說,在每一個可用磁盤上有一個(且很少於一個)容器。
有多少個表空間,就應該在每一個磁盤上建立相同數量的邏輯卷(UNIX)。這樣一來,每一個表空間在每一個磁盤上都有本身的邏輯卷(logical volume),用以放置容器。若是不是使用 raw device,那麼就須要在每一個邏輯卷內建立一個文件系統。
對於大型磁盤系統,應該使用單個容器。此外,還須要爲表空間設置 DB2 Profile Registry 變量 DB2_PARALLEL_IO。這一點放在 概要註冊表一節中討論。
Extent Size 指定在跳到下一個容器以前,能夠寫入到一個容器中的 PAGESIZE 頁面的數量,這個參數是在建立表空間時定義的(以後不能輕易修改)。處理較小的表時,使用較小的區段效率會更高一些。
下面的經驗法則是創建在表空間中每一個表的平均大小的基礎上的:
對於 OLAP 數據庫和大部分都要掃描(僅限於查詢)的表,或者增加速度很快的表,應使用較大的值。
若是表空間駐留在一個磁盤陣列上,則應將區段大小設置成條紋大小(也就是說,寫入到陣列中一個磁盤上的數據)。
經過使用 altER TABLESPACE 能夠輕易地修改預取大小。最優設置差很少是這樣的:
Prefetch Size = (# Containers of the table space on different physical disks) * Extent Size |
若是表空間駐留在一個磁盤陣列上,則設置以下:
PREFETCH SIZE = EXTENT SIZE * (# of non-parity disks in array)。 |
![]() ![]() |
![]()
|
多維羣集(Multidimensional clustering ,MDC)
MDC 提供了數據在多個維上的靈活的、連續的和自動的多維羣集。它提高了查詢的性能,而且減小了在插入、更新和刪除期間對 REORG 和索引維護的須要。
多維羣集從物理上把表數據同時沿着多個維羣集起來,這與使用表上的多個獨立的羣集的索引相似。MDC 一般用於幫助提升對大型表的複雜查詢的性能。這裏不須要使用 REORG 來從新羣集索引,由於 MDC 會自動地、動態地維護每一個維上的羣集。
對 於一個 MDC,最合適的是那些具備範圍、相等和鏈接謂詞的訪問多行的查詢。千萬不要使用具備唯一性的列做爲一個維,由於這樣會致使一個表沒必要要地變大。若是具備 每種維值組合(即單元)的行不是不少,應避免使用太多的維。爲得到最佳的性能,那麼至少須要有足夠的行來填滿每一個單元的塊,也就是該表所在表空間的區段大 小。
MQT 可用於提高使用 GROUP BY、GROUPING、RANK 或 ROLLUP OLAP 函數的查詢的性能。MQT 的使用對用戶來講是透明的,DB2 選擇什麼時候使用 MQT 來達到優化的目的。DB2 使用 MQT 在內部維護被查詢的分組的總結結果,這樣用戶就能夠直接訪問 DB2 維護的分組,而沒必要去讀動輒數 GB 的數據來尋找答案。這些 MQT 還能夠在分區間複製,以免這種信息在分區間的散播,從而幫助提高合併鏈接(collocated jion)的性能。
對於 30 字節或更少字節的列,應避免使用 VARCHAR 數據類型,由於這種狀況下,VARCHAR 類型一般會浪費空間,因此建議使用 CHAR 類型。若是數據量很大,那麼空間的浪費每每會對查詢時間形成影響。
當使用 IDENTITY或 SEQUENCE時,應至少使用缺省的大小爲 20 的緩存(除非編號中的間隔頗有干係)。這樣一來,就沒必要在每次須要的時候請求 DBM 生成一個數字,同時也避免了在生成數字時要作的日誌記錄。
當一個表使用不少空值和系統缺省值時, VALUE COMPRESSION和 COMPRESS SYSTEM DEFAULT能夠節省磁盤空間。系統缺省值是指在沒有指定特定的值時,爲某個數據類型而使用的缺省值。若是量很大,這樣還能夠幫助縮短查詢時間。若是插入或者更新一個值,壓縮的列只會招致不多的開銷。
對於有大量插入操做的表,使用 APPEND ON以免在插入過程當中搜索空閒空間,而只需將行附加在表的最後。若是要依賴於處於某種特殊順序中的表,而且沒法承受執行 REORG 的開銷,那麼應避免使用 APPEND ON。
對於只讀的表或者獨佔訪問的表,將 LOCKSIZE設置爲 TABLE。這樣就避免了爲行加鎖時所費的時間,而且減小了所需的 LOCKLIST 數量。
使用 PCTFREE來維護空閒空間,以助未來的 INSERT、LOAD 和 REORG 一臂之力。PCTFREE 的缺省值是 10;對於具備羣集索引和插入量很大的表,能夠嘗試使用 20-35。若是使用 APPEND ON,則將 PCTFREE 設置爲 0。
使用 VOLATILE來 鼓勵索引掃描。易變(volatile)代表表的基數能夠在很大的範圍內顯著變化,從一個很大的數一直到空。這樣就促使優化器無論表的統計數字如何,都使 用索引掃描,而不是使用表掃描。不過,只有在索引包含全部被引用的列,或者索引能夠在索引掃描時應用謂詞的狀況下,上述狀況纔會出現。
使用 NOT LOGGED INITIALLY將事務執行期間(也就是直到 COMMIT)的日誌記錄關閉掉。
VALUE COMPRESSION和 COMPRESS SYSTEM DEFAULT還能夠用在 altER TABLE 命令中。
![]() ![]() |
因爲有了 Design Advisor,設計索引的負擔已經消除。Design Advisor 用於爲特定的 SQL 工做負載(即一組 SQL 語句)推薦和評估索引, 很快咱們就將討論這個工具。
下面仍然是一些您應該知道的跟索引有關的問題:
我 們能夠建立羣集索引來爲表中的行排序,而且是按照所需結果集的物理順序來排序。羣集索引能夠用 CREATE INDEX 語句的 CLUSTER 選項來建立。爲得到最佳性能,應該在那些小型的數據類型(好比整型和 char(10))、具備唯一性的列以及在範圍搜索中常常要用到的列上建立索引。
羣 集索引容許對數據頁採用更線性的訪問模式,容許更有效的預取,而且有助於避免排序。這意味着插入操做要花更多的時間,可是查詢操做會更快。當使用羣集索引 時,應考慮將數據頁和索引頁上的空閒空間增長到大約 15-35(而不是 PCTFREE 的缺省值 10),以容許大容量的插入。對於會受到大量插入操做的表,考慮使用單維的 MDC 表(或許是使用像 idcolumn/1000 或 INT(date)/100 這樣的生成列)。這將致使對數據(在維上)的塊索引,而不是按行索引。這樣產生的索引會更小一些,而且在插入期間的日誌內容也大大減小。
對於只讀表上的索引,使 PCTFREE爲 0,對於其餘索引使 PCTFREE 爲 10,以提供可用的空間,從而加快插入操做的速度。此外 ,對於有羣集索引的表,這個值應該更大一些,以確保羣集索引不會被分紅太多的碎片。若是存在大量的插入操做,那麼使用 15 ' 35 之間的值或許更合適一些。
使用 ALLOW REVERSE SCANS以即可以對一個索引進行雙向(bi-directionally)掃描,也就是說,能夠對按升序排列的結果集和按降序排列的結果集進行更快速的檢索。這樣作尚未負面的性能影響,由於在爲這個特性提供支持的過程當中,並無在內部改變索引的結構。
可使用 INCLUDE將其餘沒有被索引的列包括到索引頁中來,以促進純索引訪問,並避免了從數據頁取數據。
可使用 UNIQUE 列來有效地實施一個列或一組列的唯一性。
TYPE-2 INDEXES可 以大大減小 next-key 鎖,容許索引列大於缺省的 255 字節,容許在線 REORG 和 RUNSTATS,而且支持新的多維羣集功能。在 v8 中,全部新的索引都是以 type-2 類型建立的,只有已經在表上定義了(遷移前) type-1 索引的時候纔是例外。可使用 REORG INDEXES 將 type-1 索引轉換爲 type-2 索引。
![]() ![]() |
![]()
|
DB2 概要註冊表變量一般要影響優化器和 DB2 引擎自己的行爲。雖然概要註冊表變量有不少,可是其中的大部分都有其很是特定的用途,於是在大部分的 DB2 環境中都不會用到。下面是一些經常使用的概要註冊表變量。
表 2列出了用於概要註冊表一些基本管理命令:
命令 | 描述 |
db2set -all | 列出全部當前設置的 DB2 註冊表變量 |
db2set -g | -ivariable=value | 設置指定的 DB2 註冊表變量,使其或者處於全局(-g)級,或者處於實例(-i)級 |
注意:在變量和值之間不要有空格,不然變量又會從新被設置成缺省值。
DB2_PARALLEL_IO
這 將幫助促使對駐留在磁盤陣列上的任何表空間採用並行訪問。若是全部表空間都在磁盤陣列上,則將該變量設置成等於 *。若是隻有一些表空間在磁盤陣列上,則使用 "db2 list tablespaces" 檢索這些表空間的 ID,並將該變量設置成這些 ID(使用逗號將各 ID 分隔開)。爲得到最佳性能,應確保表空間的預取大小明顯大於它的區段大小。
DB2_EVALUNCOMMITTED
缺省值是 OFF,若是將其改成 ON,則會將鎖操做推遲到謂詞演算。啓用這個變量對於減小從 Oracle 移植過來的應用程序中存在的鎖爭用十分有用。
DB2_SKIPDELETED
缺省值是 OFF,若是將其改成 ON,則容許使用 CS 或 RS 的語句略過索引中被刪除的鍵以及表中被刪除的行。一樣,啓用這個變量對於減小從 Oracle 移植過來的應用程序中存在的鎖爭用十分有用。
DB2_HASH_JOIN
缺省值是 Enabled。若是禁用 DB2_HASH_JOIN(NO),則 OLTP 可能受益。
(AIX): DB2_FORCE_FCM_BP
缺 省值是 NO。若是使用了 DB2 的 Database Partitioning Feature (DPF) 功能,而且有多個邏輯分區,那麼將該變量設置爲 YES 能夠改善分區間的通訊,代價是可供緩衝池使用的共享內存段要少掉一個。若是沒有使用數據庫分區功能,則應使用 NO 值。
(AIX 4.3) DB2_MMAP_READ 和 DB2_MMAP_WRITE
缺 省狀況下二者都處於啓用狀態的。若是使用 AIX 4.3,32 位的 DB2,而且內存會限制增長緩衝池的大小,那麼應將此變量設置成 OFF,以便多釋放一個內存段。這樣大約能夠釋放 256 MB 的共享內存(這樣就能夠將其中一部分用於緩衝池)。能夠進行一些測試,以確信這一更改的確提高了性能,由於有時候對磁盤使用內存映射的讀和寫比起增長緩衝 池大小來能夠得到更好的性能,雖然這種作法並不常見。
![]() ![]() |
![]()
|
應用程序開始運行的時候,一般會暴露出與某些配置參數有關的問題。若是在應用程序運行期間沒有收到任何錯誤或警告信息,那麼就是安全的。若是收到了這樣的信息,那麼請參閱本文後面對 數據庫管理器和數據庫配置參數管理的討論。若是沒有足夠的內存來處理 SQL,下面的一些配置參數就會出問題:
MON_HEAP_SZ (DBM)
這 是爲數據庫系統監視器(system monitor)數據分配的內存數量。當執行諸如快照監視或激活一個事件監視器之類的數據庫監控活動時,就要從監視器堆中分配內存。若是沒有足夠的可用內 存,而且 DB2 返回一個錯誤,則能夠試着將這個值設爲 256。若是仍是遇到錯誤,一次一次地增長 256,直到錯誤消失。
QUERY_HEAP_SZ (DBM)
這 是爲了將每一個查詢存儲到代理的私有內存時能夠分配的最大內存量。查詢堆還可用於爲塊遊標(blocking cursor)提供內存分配。查詢堆的大小必須大於或等於 ASLHEAPSZ。若是收到 DB2 返回的一個錯誤,代表性能可能不是最優,而處於最低狀態,那麼可將此參數設爲至少大於 ASLHEAPSZ 的五倍,這樣就容許查詢大於 ASLHEAPSZ,而且爲 3 個或 4 個併發的塊遊標足夠的內存。
MAXAPPLS (DB)
該參數指定能夠鏈接(包括本地鏈接和遠程鏈接)到一個數據庫的併發的應用程序的最大數目。在絕對最小值狀況下,將此參數設置爲 >= (用戶鏈接的數量)。要了解詳細信息,請參閱本文後面對 MAXAGENTS的討論。
STMTHEAP (DB)
語句堆用於在 SQL 語句的編譯期間做爲編譯器的工做區。對於每一條要處理的 SQL 語句,都要從該區域分配和釋放空間。若是收到警告信息或錯誤信息,那麼能夠按 256 逐次增長,直到錯誤消失。
APPLHEAPSZ (DB)
應 用程序堆是供數據庫管理器表明某個特定代理使用的私有內存。當代理或子代理要爲應用程序而初始化時,就要從這個堆中分配內存,而且所分配的內存數量是處理 請求時所需的最小內存量,若是須要更多的內存,則最多能夠從堆中分配由該參數指定的一個最大值那麼多的內存。按 256 逐次增長,直到錯誤消失。
![]() ![]() |
![]()
|
使 用快照監視來識別數據庫在一段時間裏的行爲,顯示一些諸如內存使用狀況和鎖的得到過程之類的信息。監控是用於微調配置和識別問題(例如語句執行時間較長) 的一種方法。若是已經使用了 Configuration Advisor,那麼這裏可能沒法在性能上得到什麼好處。
要收集供分析的數據,最容易的方法是在應用程序運行的時候用一個腳原本執行抽樣的快照監視。像 清單 3中或者 清單 4中顯示的腳本將會收集您進入下一步以前所需的全部信息。首先在 60 秒的一段時間內運行該腳本,其中有幾回間歇;這樣應該能夠對應用程序行爲的一個較好的抽樣,而且不會有太多的信息要處理。
#!/usr/bin/ksh # take a snapshot after specified sleep period for a number of iterations # parameters: (1) database name # (2) directory for output # (3) interval between iterations (seconds) # (4) maximum number of iterations # # Note: You may receive an error about the monitor heap being too small. You may # want to set mon_heap_sz to 2048 while monitoring. if [ $# -ne 4 ] then echo "4 parameters required: dbname output_dir sleep_interval iterations"; exit fi dbname=$1 runDir=$2 sleep_interval=$3 iterations=$4 stat_interval=3 stat_iterations=$(($sleep_interval/$stat_interval)) if [[ -d $runDir ]]; then echo "dir: $runDir already exists, either remove it or 使用 another directory name" exit fi mkdir $runDir cd $runDir db2 update monitor switches using bufferpool on lock on sort on statement on \\ table on uow on # repeat the snapshot loop for the specified iterations let i=1 while [ i -le $iterations ] do if [ $i -le 9 ] then i2="0$i" else i2="$i" fi echo "Iteration $i2 (of $iterations) starting at `date`" vmstat $stat_interval $stat_iterations > vmstat_$i2 iostat $stat_interval $stat_iterations > iostat_$i2 db2 -v reset monitor all sleep $sleep_interval db2 -v get snapshot for dbm > snap_$i2 db2 -v get snapshot for all on $dbname >> snap_$i2 echo "Iteration $i2 (of $iterations) complete at `date`" let i=$i+1 done db2 update monitor switches using bufferpool off lock off sort off statement off \\ table off uow off db2 terminate |
@echo off REM REM take a snapshot after specified sleep period for a number of iterations REM parameters: (1) database name REM (2) file name id REM (3) interval between iterations (seconds) REM (4) maximum number of iterations REM REM Note: You may receive an error about the monitor heap being too small. You may REM want to set mon_heap_sz to 2048 while monitoring. :CHECKINPUT IF ""=="%4" GOTO INPUTERROR GOTO STARTPRG :INPUTERROR echo %0 requires 4 parameters: dbname filename_id sleep_interval iterations echo e.g. "getsnap.bat sample 0302 60 3" GOTO END :STARTPRG SET dbname=%1 SET fileid=%2 SET sleep_interval=%3 SET iterations=%4 db2 update monitor switches using bufferpool on lock on sort on statement on table on uow on REM repeat the snapshot loop for the specified iterations SET i=1 :SNAPLOOP IF %i% LSS 10 SET i2=0%i% IF %i% GTR 9 SET i2=%i% echo Starting Iteration %i2% (of %iterations%) db2 -v reset monitor all sleep %sleep_interval% db2 -v get snapshot for dbm > snap%i2%_%fileid% db2 -v get snapshot for all on %dbname% >> snap%i2%_%fileid% echo Completing Iteration %i2% (of %iterations%) SET /a i+=1 IF %i% GTR %iterations% GOTO ENDLOOP GOTO SNAPLOOP :ENDLOOP db2 update monitor switches using bufferpool off lock off sort off statement off table off uow off db2 terminate :END |
注意,這兩個腳本在行爲上稍有不一樣,可是均可以產生所需的快照輸出。
在後面的一些小節中,快照監視可用做尋找 DBM 和 DB 配置參數的最優設置的一種方式。
清單 3和 清單 4中顯示的腳本將發出一個 "get snapshot for all on dbname" 命令,該命令包括 "get snapshot for dynamic SQL on dbname" 命令的全部輸出。若是您發現不會捕獲不少的 SQL 語句,那麼能夠增長監控的歷時。一條語句的輸出的 "Dynamic SQL Snapshot Result" 部分看上去如 清單 5所示:
Dynamic SQL Snapshot Result Database name = SAMPLE Database path = C:\\DB2\\NODE0000\\SQL00003\\ Number of executions = 1 Number of compilations = 1 Worst preparation time (ms) = 1624 Best preparation time (ms) = 1624 Internal rows deleted = 0 Internal rows inserted = 0 Rows read = 41 Internal rows updated = 0 Rows written = 0 Statement sorts = 0 Total execution time (sec.ms) = 0.134186 Total user cpu time (sec.ms) = 0.000000 Total system cpu time (sec.ms) = 0.000000 Statement text = select * from sales ... |
您能夠看到,在輸出中能夠搜索一些頗有用的字符串。
"Number of executions"- 能夠幫助您找到應該調優的那些重要語句。它對於幫助計算語句的平均執行時間也頗有用。
對於執行時間很長的語句,單獨執行一次或許對系統要求很少,可是累加起來的結果就會大大下降性能。應儘可能理解應用程序如何使用該 SQL,或許只需對應用程序邏輯稍微從新設計一下就能夠提升性能。
看看是否可使用參數標記(parameter marker),以便只需爲語句建立一個包,這一點也很管用。參數標記 可用做動態準備的語句(生成訪問計劃時)中的佔位符。在執行的時候,就能夠將值提供給這些參數標記 marker,從而使語句得以運行。
例如,要搜索執行得最頻繁的語句:
UNIX:
grep -n " Number of executions" snap.out | grep -v "= 0" | sort -k 5,5rn | more |
Windows:
findstr /C:" Number of executions" snap.out | findstr /V /C:"= 0" |
"Rows read"- 可幫助識別讀取行數最多的 Dynamic SQL 語句。若是讀取的行數不少,一般意味着要進行表掃描。若是這個值很高,也可能代表要進行索引掃描,掃描時選擇性很小,或者沒有選擇性,這跟表掃描同樣糟糕。
您 可用使用 Explain 來查看是否真的如此。若是有表掃描發生,那麼能夠對錶執行一次 RUNSTATS,或者將 SQL 語句提供給 DB2 Design Advisor,以便令其推薦一個更好的索引,以此來進行彌補。若是是選擇性不好的索引掃描,或許須要一個更好的索引。能夠試試 Design Advisor。
grep -n " Rows read" snap.out | grep -v "= 0" | sort -k 5,5rn |
findstr /C:" Rows read" snap.out | findstr /V /C:"= 0" |
"Total execution time" - 這是將語句每次執行時間加起來獲得的總執行時間。咱們能夠很方便地將這個數字除以執行的次數。若是發現語句的平均執行時間很長,那麼多是由於表掃描和/ 或出現鎖等待(lock-wait)的狀況。索引掃描和頁面獲取致使的大量 I/O 活動也是一個緣由。經過使用索引,一般能夠避免表掃描和鎖等待。鎖會在提交的時候解除,所以若是提交得更頻繁一些,或許能夠彌補鎖等的問題。
grep -n " Total execution time" snap.out | grep -v "= 0.0" | sort -k 5,5rn | more |
findstr /C:" Total execution time" snap.out | findstr /V /C:"= 0.0" |sort /R |
"Statement text"顯 示語句文本。若是注意到了重複的語句,這些語句除了 WHERE 子句中謂詞的值有所不一樣之外,其餘地方都是一致的,那麼就可使用參數標記,以免從新編譯語句。這樣可使用相同的包,從而幫助避免重複的語句準備,而 這種準備的消耗是比較大的。還能夠將語句文本輸入到 Design Advisor 中,以便生成最優的索引。
grep -n " Statement text" snap.out | more |
findstr /C:"Statement text" snap.out |
經過使用 "get snapshot for all on dbname" 能夠爲數據庫上的每一個緩衝池生成一個快照。 清單 6展現了那樣一個快照:
Bufferpool Snapshot Bufferpool name = IBMDEFAULTBP Database name = SAMPLE Database path = C:\\DB2\\NODE0000\\SQL00002\\ Input database alias = SAMPLE Snapshot timestamp = 02-20-2004 06:24:45.991065 Buffer pool data logical reads = 370 |
爲了判斷一個緩衝池的效率,須要計算它的緩衝池命中率(BPHR)。您所需的重要信息在上面已經用粗體標出來了。若是可能的話,一個理想的 BPHR 在某些地方應超過 90%。公式以下:
BPHR (%) = (1 - (("Buffer pool data physical reads" + "Buffer pool index physical reads") / ("Buffer pool data logical reads" + "Buffer pool index logical reads"))) * 100 |
在 IBMDEFAULTBP 緩衝池的 以上快照中,咱們能夠這樣來計算 BPHR:
= (1-((54 + 94) / (370 + 221))) * 100 = (1-(148 / 591)) * 100 = (1- 0.2504) * 100 = 74.96 |
在這種狀況下,BPHR 大約等於 75%。當前,緩衝池只有 250 * 4KB 頁(1MB)。增長該緩衝池的大小,看看 BPHR 是否會隨之增長,這樣作是值得的。若是 BPHR 仍是比較低,那麼可能就須要像 建立緩衝池和 建立表空間這兩節中討論的那樣從新設計邏輯佈局。
基於塊的緩衝池的效率
如 果是一個基於塊的緩衝池,而且看到 "Block IOs" 的值較低,那麼應考慮修改緩衝池,增長 NUMBLOCKPAGES 的大小。若是這時看到 "Block IOs" 的值更大了,則能夠考慮將 NUMBLOCKPAGES 再增大一些。若是結果拔苗助長,則應減少 NUMBLOCKPAGES 的大小。
DB2 有幾十個配置參數。不少參數都是由 DB2 自動配置的,而其餘一些參數都有它們的缺省值,這些缺省值都被證實在大多數環境中可以發揮得很好。接下來,咱們只描述那些經常須要另外進行配置的參數。
有 些數據庫管理器(即實例)配置參數能夠在線更改(當即生效),而另外一些參數則要求對實例實行再循環(即 DB2STOP 以後接着又是 DB2START)。對於數據庫配置參數也是同樣。有些參數的更改能夠當即生效,而另外一些參數則要求先中止數據庫,再從新激活數據庫。關於每種配置參數的 文檔都規定了參數是否能夠在線配置。
數據庫管理器和數據庫配置文件的基本管理命令如 表 3所示:
命令 | 描述 |
GET DBM CFG [SHOW DETAIL] | 列出數據庫管理器配置文件中的當前值 |
UPDATE DBM CFG USINGconfig_param value | 將指定的數據庫管理器配置參數設置成指定的值 |
GET DB CFG FORdb_name[SHOW DETAIL] | 列出某個特定數據庫的配置文件中的當前值 |
UPDATE DB CFG FORdb_nameUSING config_param value | 將指定的數據庫管理器配置參數設置成指定的值 |
當您對一個配置參數做了更改時,就能夠用下面的 DB2 CLP 命令查看該設置是否當即生效(在線):
GET DBM CFG SHOW DETAIL
GET DB CFG FOR dbname SHOW DETAIL
例 如,在接下來的狀況中,MAX_QUERYDEGREE 和 MAXTOTFILOP 分別增長到了 3 和 19000。若是參數是在線配置的,則 Delayed Value 跟 Current Value 應該是同樣的。不然,就須要從新啓動實例,或者從新激活數據庫。
Database Manager Configuration Node type = Enterprise Server Edition with local and remote clients Description Parameter Current Value Delayed Value ------------------------------------------------------------------------------------------- Maximum query degree of parallelism (MAX_QUERYDEGREE) = 3 3 Maximum total of files open (MAXTOTFILOP) = 16000 19000 |
下面的配置參數中,有些是從共享內存分配空間的,因此應該記住 OS 的限制(在 前面已討論)。您必須確保沒有過分分配內存。若是過分分配內存,就會致使操做系統發生換頁(page),這對於性能來講是災難性的。
清單 8和 清單 9顯示了一個數據庫管理器和數據庫快照的示例。順着右邊(順帶提一下),能夠看到能根據輸出進行調優的配置參數。
Database Manager Snapshot Node name = Node type = Enterprise Server Edition with local and remote clients Instance name = DB2 Number of database partitions in DB2 instance = 1 Database manager status = Active Product name = DB2 v8.1.4.341 Service level = s031027 (WR21326) Private Sort heap allocated = 0 (SHEAPTHRES |
快照老是顯示 Current size (bytes) = High water mark (bytes),由於內存是在數據庫激活的時候分配的。
Database Snapshot Database name = SAMPLE Database path = C:\\DB2\\NODE0000\\SQL00002\\ Input database alias = SAMPLE Database status = Active Catalog database partition number = 0 Catalog network node name = Operating system running at database server= NT Location of the database = Local First database connect timestamp = 02-20-2004 06:19:00.847979 Last reset timestamp = Last backup timestamp = Snapshot timestamp = 02-20-2004 06:23:17.252491 High water mark for connections = 1 (MAXAPPLS) Application connects = 1 Secondary connects total = 0 Applications connected currently = 1 (AVG_APPLS) Appls. executing in db manager currently = 0 Agents associated with applications = 1 Maximum agents associated with applications= 1 Maximum coordinating agents = 1 Locks held currently = 0 Lock waits = 0 Time database waited on locks (ms) = 0 Lock list memory in 使用 (Bytes) = 1000 (LOCKLIST and MAXLOCKS) Deadlocks detected = 0 Lock escalations = 0 (LOCKLIST and MAXLOCKS) |
有時候,爲了某些問題使用 "grep" (UNIX) 和 "findstr" (Windows) 對快照輸出執行初步的搜索很是方便。若是發現了什麼東西,就能夠經過打開快照輸出並找到問題所在,以便做進一步調查。
例如,爲了識別是否存在死鎖:
UNIX:
grep -n "Deadlocks detected" snap.out | grep -v "= 0" | more
Windows:
findstr /C:"Deadlocks detected" snap.out | findstr /V /C:"= 0"
SHEAPTHRES (DBM)
這是實例中全部數據庫的併發私有排序 所消耗的內存總量。另外傳入的排序只能獲得更少許的可用內存。對於 OLTP,一開始最好是使用大約 20000,而對於 OLAP 40000-60000 會工做得更好一些。
當 "Piped sorts accepted"的值與 "Piped sorts requested" 比起來較低時,經過增長 SHEAPTHRES 的大小,經常能夠提升性能。若是 "Post threshold sorts" (在 SHEAPTHRES 已經被超出以後,請求堆的排序) 的值較高(也就是有兩位數),應嘗試增長 SHEAPTHRES 的大小。 "Total Private Sort heap allocated"應該小於 SHEAPTHRES。若是不是這樣,則應增長 SHEAPTHRES。
MAXAGENTS (DBM)
這是可用於接受對實例中全部數據庫的應用程序請求的數據庫管理器代理的最多數量。在受限內存(memory constrained)的環境中,這個參數對於限制數據庫管理器的總內存使用量頗有用,由於每一個附加的代理都須要附加的內存。
若是機器是受限內存的,那麼能夠增長 MAXAGENTS,直到 "Agents stolen from another application"爲 0。此外, "Local connections"+ "Remote connections to db manager"將指出鏈接到實例上的併發鏈接的數量。 "High water mark for agents registered"將報告在某一次鏈接到數據庫管理器的代理曾出現的最大數量。"Max agents overflow"報告當已經達到 MAXAGENTS 時,所收到的建立一個新代理的請求的次數。最後, "Agents Registered"顯示在被監控的數據庫管理器實例中當前註冊的代理的數量。
NUMDB (DBM)
指定能夠同時激活的本地數據庫的數量。在生產系統中,建議每一個實例有一個數據庫,所以應該將這個值設爲 1。不然,將其設爲同時激活的數據庫的最大數量。若是不肯定的話,使用 "Active local databases"。
NUM_INITAGENTS 和 NUM_POOLAGENTS (DBM)
NUM_INITAGENTS 指定在 db2start 上的池中建立的空閒代理的數量,它能夠幫助加快在開始使用數據庫時的鏈接。NUM_POOLAGENTS 也是相關的,可是若是數據庫已經運行了一段時間,那麼它對性能會有更大的影響。當 Connections Concentrator 爲 OFF(缺省值;MAX_CONNECTIONS = MAX_COORDAGENTS)時,NUM_POOLAGENTS 指定代理池的最大大小。當 Concentrator 爲 ON (MAXCONNECTIONS > MAX_COORDAGENTS)時,能夠參考這個值來決定在系統工做負載較低時代理池應該有多大。
NUM_INITAGENTS 和 NUM_POOLAGENTS 應該設爲預期的併發實例級鏈接的平均數量,對於 OLAP 這個值一般比較低,而對於 OLTP 就要高一些。對於存在大量 ramp up 鏈接狀況下的性能基準,將 NUM_INITAGENTS 設置成預期的鏈接數量(這將減小資源爭用,從而顯著地減小 ramp up 鏈接所需的時間)。在使用了鏈接池的 3 層環境中,NUM_INITAGENTS 和 NUM_POOLAGENTS 對性能的影響很小,由於即便在應用程序空閒的時候,應用服務器也會接二連三地維護鏈接。
"Idle agents"顯示了在代理池中空閒代理的數量,而 "Agents assigned from pool"則顯示從代理池中將一個代理分配出去的次數。 "Agents created from empty pool"顯示在空池狀況下必須建立的代理的數量,這可能會讓人誤解爲恰好在 db2start 以後。而在 db2start 以後,它只是顯示被建立的代理的數量。若是 "Agents created from empty pool"/ "Agents assigned from pool"的 比例比較高(5:1 或更大),則可能代表應該增長 NUM_POOLAGENTS。這也可能代表系統的整體工做負載過高。這時能夠經過下降 MAXCAGENTS 來調整工做負載。若是這個比例較低,則暗示着 NUM_POOLAGENTS 可能被設得過高,有些代理就會浪費系統資源。
FCM_NUM_BUFFERS (DBM)
只在有多個邏輯分區的 DPF 環境中使用。它指定用於內部通訊的大小爲 4 KB 的緩衝區的數量。若是沒有使用 DPF,那麼這個值甚至不會出如今快照輸出中。此外,該信息未來自其上運行了快照的分區。例如,在 DBM 快照以前的那個快照中, "Node FCM information corresponds to"顯示了一個值 2,所以它是從 2 號分區那裏得來的。"Get snapshot for dbm global" 可用於得到全部分區值的羣集。
DBM 快照的 FCM Node 部分可用於查看主要的分區間通訊發生的地點,以用於調查的目的。若是通訊量很大,則代表須要更多的 FCM 緩衝區內存,須要不一樣的分區鍵,或者須要不一樣的表來分派表空間。若是 "Free FCM buffers low water mark"小於 FCM_NUM_BUFFERS 的百分之 15,那麼能夠增長 FCM_NUM_BUFFERS,直到 "Free FCM buffers low water mark"大於或等於 FCM_NUM_BUFFERS 的百分之 15,以確保總有足夠的 FCM 資源可供使用。
AVG_APPLS (DB)
只有在應用程序發出複雜的 SQL(例如鏈接、函數、遞歸等等)時才更改它,不然讓它一直爲 1。這能夠幫助估計在運行時能夠爲一個訪問計劃提供多少的緩衝池。它應該設爲一個較低的值,即 "Applications connected currently"的平均數量乘以複雜 SQL 的百分比。
LOCKLIST 和 MAXLOCKS (DB)
對於每一個數據庫都有一個鎖列表,該列表包含全部同時鏈接到數據庫的應用程序所持有的鎖。在 32 位的平臺上,一個對象上的第一個鎖要求佔 72 字節,而其餘的鎖要求佔 36 字節。在 64 位平臺上,第一個鎖要求佔 112 字節,而其餘鎖要求佔 56 字節。
當 一個應用程序使用的 LOCKLIST 的百分比達到 MAXLOCKS 時,數據庫管理器將執行一次鎖升級(lock escalation),在這個操做中將使得行鎖換成單獨的一個表鎖。並且,若是 LOCKLIST 快要耗盡,數據庫管理器將找出持有一個表上的最多行鎖的鏈接,並將這些行鎖換成表鎖,以釋放 LOCKLIST 內存。鎖整個表能夠大大減小併發性,死鎖的概率也增長了。
若是 "Lock list memory in 使用 (Bytes)"超出了定義的 LOCKLIST 大小的 50%,那麼應增長 LOCKLIST 4 KB 大小的頁面的數量。若是發生了 "Lock escalations"或 鈥淓xclusive lock escalations鈥_,則應該或者增長 LOCKLIST,或者增長 MAXLOCKS,抑或同時增長二者。
關於鎖的數據庫快照部分包含大量有價值的信息。看看 "Locks held currently"、"Lock waits"、 "Time database waited on locks (ms)"、 "Agents currently waiting on locks"和 "Deadlocks detected"中是否存在高值,若是有的話,就多是差於最優訪問計劃、事務時間較長或者應用程序併發問題的症狀。若是要發現死鎖,那麼須要建立一個針對死鎖的事件監視器,事件監視器帶有詳細信息,以便查看當前正在發生的事情。
要了解關於鎖問題的詳細信息,請參閱 Bill Wilkins 撰寫的文章 Diagnosing and Resolving Lock Problems with DB2 Universal Database。
您能夠作下列事情來減小鎖: