(轉)Db2 數據庫性能優化中,十個共性問題及難點的處理經驗


(轉)https://mp.weixin.qq.com/s?__biz=MjM5NTk0MTM1Mw==&mid=2650629396&idx=1&sn=3ec17927b3d32c7bc9692c809d1f69cb&chksm=bef91b92898e928417a7608b2ef56deef78b184c65e5fef118dbe8708d4a2d1ebd717979e7f2&mpshare=1&scene=1&srcid=08212GNx1FDgPZQOXMQKKF3l#rd

為了幫助大家更好地進行DB2的性能優化,社區組織社區專家針對一些共性問題及難點分享經驗。以下內容來自活動“Db2數據庫性能優化經驗交流”,主要由以下社區專家及會員分享:leilin、topzgm、岳彩波、beyondmch、yellow-fin等

提醒:文章末尾有彩蛋,如果你是Db2達人,可不要錯過~

 

01

如何發現性能問題?通過什么定位?

 

1、收集信息。

2、分析

3、找到問題點解決

第一步 操作系統級別性能

CPU監控:

ps -elf | sort +5 -rn | more 第6列代表CPU使用的計數器

I/O使用率:

iostat -D 收集磁盤I/O信息

內存占用率:

討論的內存指的是虛擬內存(virtual memory),包括物理內存(physical memory)與交換空間(swap space)

vmstat -> avm 當前系統中已經激活的虛擬內存頁的數量(該數值不包含文件系統緩存)

vmstat -> fre 系統中平均空閑頁的數量(不能完全代表系統中可用的空閑內存:文件系統緩存駐留內存,並不會返還給空閑列表,除非被虛擬內存管理器盜取)

svmon -> clnt與in use交叉項 代表有多少內存被文件系統使用(加上free項,可以初步認為是該系統中可以被應用程序所使用的內存)

第二步 數據庫級別性能

1. db2grep -dump | more 查看服務器安裝了幾個DB2版本

2. ps -elf | grep db2inst1 查看數據庫進程的CPU計數器

3. db2 get dbm cfg | grep -i dft_mon 確認快照打開

4. 實例級快照,了解當前實例有多少應用程序在執行

db2 get snapshot for database manager -> Remote connections & Local connections

5. 數據庫級快照

連接數信息:applications connected currently,appls executing in db manager currently

鎖信息:鎖總數,鎖等待數量,鎖等待總時間,當前數據庫鎖列表占用內存,死鎖次數,鎖升級次數,鎖超時次數

排序信息:

排序是CPU殺手,過多的排序會造成CPU的極大消耗;

排序溢出是說,如果排序堆無法容納排序數據,就會被溢出到臨時空間;

排序是一種狀態,根源在SQL語句;

數據索引I/O信息:

邏輯讀 DB2向緩沖池請求的次數 邏輯讀越多,需要的物理I/O就越少

物理讀 如果請求的數據頁不在緩沖池,需要從磁盤中讀取數據頁的次數

吞吐量或事務信息:

提交/回滾事務數,執行動態和靜態語句次數,增刪改查次數

( rows read / rows selected ) 是一個非常重要的性能指標,它表示為了檢索一行數據需要讀取多少行,該值越大,表示代價越高,需要的I/O越多,可調優的余地越大

事務日志信息:日志I/O在很大程度上會影響數據庫整體的性能

6. 應用程序快照

在數據庫快照中發現存在大量的邏輯讀,通過應用程序快照可以細化到某條特定的語句

7. 表空間快照

在數據庫快照中發現存在大量的邏輯讀,通過表空間快照可以輕松地定位哪個表空間被頻繁使用

8. 表快照

如果發現一個表的頁數很少,但是讀的行數非常多,那么可以合理地猜測該表在某些查詢語句中可能處於NLJOIN的內部子節點

9. 動態SQL快照:SQL執行次數,總共讀的行數,消耗的CPU,邏輯物理讀數量,排序數量等

第三步 內存使用監控

1. db2pd -osinfo

系統內存使用情況

2. db2pd -dbptnmem

整個實例的內存使用情況

3. db2pd -memsets

內存段使用情況

在實例中會有多個不同的內存段,每一個內存段中可能有一個或者多個內存池

ipcs -a | grep 578814120 內存段映射到操作系統共享內存IPC段

FMP與trace內存段很少造成性能問題

4. db2pd -mempool

深入內存池信息

5. db2pd -db <dbname> -memsets / -mempool

數據庫級別內存段和內存池信息

 

02

優化過程中的優先級問題?

在Db2優化過程中,我已知的有如下手段

1.索引

2.sql語句優化(分析執行語句后重寫sql)

3.runstats信息收集

請問優化過程中,入手的優先級順序是什么呢,還有其他手段嗎?

 

這“三板斧”已經可以解決很多問題了,DB2的優化手段很多,如果想深入了解,上傳幾個文件供參考。

附件:

(以下附件在如下地址可下載:http://www.talkwithtrend.com/Question/403149)

DB2BP_System_Performance_0813.pdf 

DB2BP_Query_Tuning_0508I.pdf 

DB2BP_Storage_1009I.pdf 

DB2BP_Physical_Design_OLTP_0412.pdf

DB2BP_Physical_Design_0508I.pdf

 

03

如何監控到db2某個時段內發生的sql?以及sql的響應時間和資源消耗情況?

 

這是個共性問題,實現這個目標的DB2工具也比較多,例如:

1)SNAPSHOT管理視圖,示例腳本如下: 

db2 "select SNAPSHOT_TIMESTAMP,NUM_EXECUTIONS,TOTAL_EXEC_TIME,STMT_TEXT from sysibmadm.snapdyn_sql with ur" | more

以上快照結果存儲在數據庫中,讀取和分析方便。

2)db2top工具,示例腳本如下:

a)db2top -d xdb -f test1.txt -C -m 5 -i 30

每隔30秒取得快照一次,時間段為5分鍾

b)db2top -d xdb -f test1.txt -b D

分析剛才取得的快照數據

以上快照結果存儲在文件中,讀取和分析可能不太方便,但是收集的信息寬度更大。

 

04

臨時表的創建和維護?

在做復雜業務分析時,一個存儲過程也會用到很多臨時表(存儲業務分析某一步的中間結果),這些表的數據經常變化(每個周期都會被清空再裝入),還需要和別的表做關聯,那么這種表在建表的時候有什么要注意的嗎?為了提升程序性能,優化時考慮這些表嗎?要建立索引嗎?runstats應該保持在什么狀態?需要reorg嗎?

 

分享一:

這些臨時表不是會話表(DGTT 或 CGTT)吧?如果每次調用存儲過程生成的臨時表數據變化都比較大,建議在存儲過程中搜集統計信息(調用sysproc.admin_cmd('runstats on table <臨時表>'),因為臨時表每次調用一般都清空,沒有必要reorg;建不建索引,具體看表關聯的需要,存儲過程一般是加工數據的,臨時表一般不需要建索引。另外,建議將存儲過程對應的package綁定成 REOPT ALWAYS的,這樣每次調用該存儲過程都會根據最新的統計信息生成新的執行計划,通常也會提高性能。

分享二:

根據個人實踐經驗,分享如下2點:

1)如果是DGTT(DECLARE GLOBAL TEMPORARY TABLE)/CGTT(CREATE GLOBAL TEMPORARY TABLE),則一般不必對其建立index,也不需對其進行runstats、reorg,因為DB2查詢優化器在每次分析和執行SQL時,都會對包含DGTT/CGTT的SQL進行重新優化並且生成新的最優access plan。

2)如果不是DGTT/CGTT,而是自己create table x1的普通表,即使這些普通表經常變化,只要建立index、runstats、reorg帶來的收益遠遠大於建立index、runstats、reorg耗費的成本,就應該建立index、runstats、reorg,否則不必。復雜業務分析的存儲過程,更加需要遵從這個“收益與成本原則”。例如,一個復雜分析,不建立index/runstats/reorg時查詢需要5分鍾時間;但是如果建立index/runstats/reorg需要耗時3秒種時間,而此時查詢提高到只需10秒時間;這樣的3秒種的成本,帶來了查詢時間減少4分50秒的收益,這樣的成本與收益是有利的。

 

05

怎么查什么數據占用了系統臨時表空間呢?

 

Db2 在排序、表關聯等處理時會用到系統臨時表空間,順序是Sortheap不足時溢出到臨時表空間對應的bufferpool,buffpool再不足時溢出到磁盤。如果想看數據是否使用了系統臨時表空間、使用了多少,直接db2 list tablespaces show detail 看看系統臨時表空間的Used pages即可, 或者db2top 進去看表空間(按 t ),再看系統臨時表空間上是否有Writes。

 

06

有個表空間一直都在增長,但是查數據庫正在執行哪些sql又沒查到東西,請問是不是load的原因呢?

 

分享一:

如果沒有SQL在運行,可以用db2 list utilities 或 db2pd -util 看看是否有load在執行,並找到load表的表空間或其索引表空間,對應看一下。

分享二:

一點思路,僅供參考:

使用db2top -d xdb1,然后切換到工具的Table頁,看看這個表空間下哪些/那個表在一直讀寫。如果表空間在增長,但是在db2top中看不到該表空間下任何表在讀寫,再從load方面入手,適用db2 list utilities來看看有何進展。

 

07

lob存儲優化的問題?

請教個問題

我們有一個表很大,500G,lob大對象沒有采用內聯方式,現在要想讓它的大小縮小點,

改成內聯會有效果嗎??

2.內聯后有啥負面影響嗎?

(對查詢,DML等的性能方面)

v10.1的版本

 

分享一:

Db2 支持單獨存放大對象,也支持內聯(INLINE)方式,將大對象字段數據和別的字段數據都存放在同一個頁面中,但是LOB的大小受到Db2 Pagesize 的限制,超過頁面大小還是會單獨存放。如果您的LOB數據大多小於32K,建議使用32K的表空間,LOB INLINE方式,並且開啟Db2 壓縮,如果是聯機系統,建議使用經典壓縮(Static)方式,LOB數據通常會縮小2-3倍。由於Db2的交易日志是否壓縮取決於表是否壓縮,開啟LOB INLINE並壓縮后,數據庫的日志也會縮小很多,對於該表的交易性能也會大幅提升。查詢時,LOB INLINE通常也會提升性能,壓縮后變小使得內存利用率更充分是一個方面,批量掃描數據時,可以順序的將LOB讀進Db2的bufferpool,效率高,單獨存放時,每條記錄中的LOB字段需要1次隨機IO單獨讀取,導致性能低下,特別是是使用低性能磁盤的時候。

分享二:

縮小表可以使用壓縮

lob是否可以inline存儲取決於lob的實際長度,如果大於32K就無法使用inline存儲了

使用inline存儲性能會提高,沒啥壞處

分享三:

首先,你的lob字段應該單獨分離出來,你不管怎么改,如果和你的業務表混在一起,速度都不會有什么提升,在就是你改什么連接,你的條件不變,查出來的數據都不會改變,如何減少?

分享四:

可以考慮試試inline

 

08

有沒有一些好用的db2數據庫優化工具推薦?

 

IBM 官方的工具是DSM(Data Server Manager),包含數據庫性能監控、數據庫調優(OQWT, Optim Query Workload Tuner, 原來主機DB2上的查詢調優工具)、配置變更管理(數據庫參數變更、數據庫對象定義變更)、數據庫管理等功能。DSM支持歷史性能數據管理,不僅僅是實時性能監控。另外,在實時性能監控上,db2top就是一個很好的工具,可以幫助定位很多性能問題。

 

09

分區表刪除分區會不會出現索引失效的情況?

 

deatch 分區不會出現索引失效的情況。如果是分區索引(parttiitoned index,或本地索引),deatch分區成功后,被刪除分區和數據立刻不可見;如果是非分區索引(not partitioned index,或全局索引),detach分區成功后,Db2采用了異步 清理的方式,將對應分區在全局索引上的頁面進行清除處理,在清除期間,不影響對外提供服務,針對該表的DML操作依然可以正常進行。

 

10

容量很大的庫,一般采取什么策略來進行清理?是定期刪除,還是使用分區表?

對於數據庫容量很大的庫,一般采取什么策略來進行清理?是定期刪除,還是使用分區表?不同的方案對日志需求,備份恢復策略有什么影響?

定期刪除使用load還是delete的區別?

 

分享一:

數據清理的策略和業務直接相關,不一定按業務時間分區,清理時做分區detach就可以,在數據倉庫和分析領域,歷史數據歸檔通常卻是可以采用分區detach方式的。

刪除(delete)通常消耗大量的日志,而分區detach則不會。另外一個可選的方案是MDC fast rollout, 通過設置db2set DB2_MDC_ROLLOUT=DEFERRED實現,當delete 語句的where條件中只有MDC字段限定時,可以實現快速刪除並且只記很少的日志。

對於聯機系統,如果一次性刪除大量數據可能導致鎖升級,影響交易的並發性,建議多次小批量刪除,通常的方法是多次執行:delete from (select * from <table name> where ... fetch first 10000 rows only);

detele不影響備份恢復策略;detach 是DDL操作,影響了表的定義,也就影響了表空間的MRT(Minimum Recovery Time),PIT恢復時必須恢復到detach操作時間點以后。

表清空可以采用load/import (load/import from /dev/null of del replace into <table name>) ,或是truncate (truncate table <table name> immediate), 或是關閉日志的操作(alter table <table name> activate not logged with empty table),也可以是是帶任何條件的delete。除了delete需要記錄大量的日志外,別的操作記錄的日志很少或不記日志。

分享二:

第一,容量很大的必須用分區表

第二、刪除的可以可以按分區刪除,或者按分區歸檔數據。

分享三:

數據生命周期的管理是數據倉庫(容量很大的庫)的管理重點之一。

1.要有嚴格的建表審查機制,在表建立的時候就應對表的數據增長有預期,選擇合適的表屬性

2.對於大容量表,分區表是最合適的,卸載分區和重新掛載分區都很方便

3.很少有表會全部清空,所以如果不是分區表一般都在做delete

4.備份一般都是增量的,花的時間比刪除還多

分享四:

采用分區表,以日期作為分區鍵,按分區的周期拆離分區

按這個方法跑了6年左右了,效果還行


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM