如何调整DB2 数据库 性能实用技巧分享,呵呵,废话就多说了,看资料了,可能对你有有所帮助,学习咯
1.SQLCOSTANALYSIS
许多情况下,一个简单的SQL就可能让DB2处于尴尬的状态。调整参数也不能解决此问题。由于DBA很难去改变这些垃圾SQL的现状,所以留给DBA的就是下面的情况:
(1).Changeoraddindexes
(2).Changeclustering
(3).Changecatalogstatistics.
注:一个SQL语句的cost=每次执行的资源代价*执行的次数。
目 前,DBA面临的挑战就是要找到那些有很高cost的语句,并且尽力去减少它的代价。可以借助DB2Explain工具或者 DB2UDBSQLEventMonitor数据来分析SQL语句的代价。尤其是对SQLEventMonitor的数据分析,但这么做需要 耗费很大的精力和时间。
一般DBA的流程是:
(1).CreateanSQLEventMonitor,writetofile:
$>db2"createeventmonitorSQLCOSTforstatementswriteto..."
(2).Activatetheeventmonitor(besureamplefreediskspaceisavailable):
$>db2"seteventmonitorSQLCOSTstate=1"
(3).Lettheapplicationrun.
(4).Deactivatetheeventmonitor:
$>db2"seteventmonitorSQLCOSTstate=0"
(5).UsetheDB2-supplieddb2evmontooltoformattherawSQLEventMonitordata(hundredsofmegabytesoffreediskspacemayberequireddependingonSQLthroughputrates):
$>db2evmon-dbDBNAME-evmSQLCOST
>sqltrace.txt
(6).Browsethroughtheformattedfilescanningforunusuallylargecostnumbers,atime-consumingprocess:
$>moresqltrace.txt
(7).Undertakeamorecompleteanalysisoftheformattedfilethatattemptstoidentifyuniquestatements(independentofliteralvalues),eachuniquestatement’sfrequency(howmanytimesitoccurred),andtheaggregateofitstotalCPU,sort,andotherresourcecosts.Suchathoroughanalysiscouldtakeaweekormoreonjusta30-minutesampleofapplicationSQLactivity.
为了以最快的速度找到相应的SQL,我们可以考虑上文讲过的一些方法:
针对第4个tip:计算每个交易从一个table里面取出的行数。如果数值很高,就可以找到相应的语句。
针 对第3个tip:计算每个tablespace的 asynchronousreadpercentageandphysicalI/Oreadrates.如果一个tablespace有 很高的asynchronousreadpercentage和高于平均的physicalI/Oreadrates,那么有可能这个 tablesapce里面有tablescan情况。从catalog中可以找寻tablespace中相应的table(如果一个 tablespace上只有一个表,那么很容易定位了),然后从SQLEventMonitor中寻找相关的table。这样也可以缩小范围。
观察DB2Explain信息,寻找可疑的地方。有时候,经常执行的、而且是代价比较低的语句也会疯狂占用系统资源!
很多时候,我们可以充分借助工具!这样能省时省力。
StayinginTune
需要特别注意的是,性能优化不能仅仅只是消除那些好的SQL语句,也要保证合理的物理构架,确保高性能的结果、内存分配在pool和heap中,I/O都在DISk之间平衡分布。
2.BUFFERPOOLOPTIMIZATION
目 前一般的系统内存都可以达到2G,4G,8G了,但是DB2缺省的IBMDEFAULTBP只有16M。在此情况下,一般可以建立一个 bufferpool给SYSCATSPACEcatalogtablespace,一个bufferpool 给TEMPSPACEtablespace,至少两个BP_RANDandBP_SEQ.随机存取的Tablespaces应该有一个 bufferpool来应付随机的objectives,这就是BP_RAND.顺序存取的 Tablespaces(withasynchronousprefetchI/O)应该建立一个bufferpool给 sequentialobjectives,BP_SEQ.也可以建立其它的bufferpools,这要根据应用来说。比如可以建立一个足够大 的bufferpool来存放热点经常存取的数据。有时候需要为大的table建立单一的bufferpool.
太小的bufferpool会导致大量的、不必要的物理I/O。太大的bifferpool有可能会产生系统paging,增加不必要的CPU管理内存开销。
bufferpool 的大与小是相对的,一个系统的bufferpool大小应该"合适的"!当达到diminishingreturn达到时,就是合适的。如果不是使用 自动工具,应该有条理的测试bufferpool性能,比如命中率,I/O次数,物理I/O读的比率,直到达到合适状态。当然,应用是变化的,所以最优 状态不是不边的,也是要定期的评估。
3.TABLESPACEANALYSIS
tablespacesnapshot对理解哪些数据被访问和怎么访问的有很大的价值。
db2"getsnapshotfortablespacesonDBNAME"
对每一个tablespace,要注意:
Whatistheaveragereadtime(ms)?
Whatistheaveragewritetime(ms)?
WhatpercentageofthephysicalI/Oisasynchronous(prefetched)vs.synchronous(random)?
Whatarethebufferpoolhitratiosforeachtablespace?
Howmanyphysicalpagesarebeingreadeachminute?
Howmanyphysicalandlogicalpagesarebeingreadforeachtransaction?
对所有的tablespaces,注意:
Whichtablespaceshavetheslowestreadandwritetimes?Why?
Containersonslowdisks?Arecontainersizesunequal?
attributes,asynchronousversussynchronousaccess,consistentwithexpectations?
Randomlyreadtablesshouldhaverandomlyreadtablespaces,meaninghighsynchronousreadpercentages,usuallyhigherbufferpoolhitratios,andlowerphysicalI/Orates.
对每个tablespace,要注意Prefetchsize是Extentsize的倍数。如果必要,可以修改tablespace的prefetchsize。
显示tablespace信息:db2"listtablespacesshowdetail"
显示containers信息:db2"listtablespacecontainersforNshowdetail"
4.TABLEACCESS
要查出来每次查询读出的row,
1)db2"getsnapshotfordatabaseonDBNAME"
看到多少交易发生,thesumofCommitstatementsattempted+Rollbackstatementsattempted
2)db2"getsnapshotfortablesonDBNAME"
区 分出交易读出的row。 dividethenumberofrowsreadbythenumberoftransactions(RowsPerTX).OLTP 一般每次交易从一个table里面读出20row,如果发现一个交易能读出成百上千行数据,表扫描就可能出现,可能需要看看index是否需要。简单情 况下是运行runstats收集信息。
Sampleoutputfrom"getsnapshotfortablesonDBNAME"follows:
Snapshottimestamp=09-25-20004:47:09.970811
Databasename=DGIDB
Databasepath=/fs/inst1/inst1/NODE0000/SQL00001/
Inputdatabasealias=DGIDB
Numberofaccessedtables=8
TableList
TableSchema=INST1
TableName=DGI_SALES_LOGS_TB
TableType=User
RowsWritten=0
RowsRead=98857
Overflows=0
PageReorgs=0
有很高的Overflows,就需要re-orgtable。当一行宽度改变,可能DB2就会把一行放到不同的页中。
5.SORTMEMORY
OLTP应该没有大规模的sort,因为sort会消耗大量的CPU,I/O和时间。
缺省的SORTHEAP=256*4K=1M,一般是足够了。应该知道sortoverflows的数目和每个交易的sortnumber。
Db2"getsnapshotfordatabaseonDBNAME"
察看如下项目:
Totalsortheapallocated=0
Totalsorts=1
Totalsorttime(ms)=8
Sortoverflows=0
Activesorts=0
Commitstatementsattempted=3
Rollbackstatementsattempted=0
Lettransactions=Commitstatementsattempted+Rollbackstatements
attempted
LetSortsPerTX=Totalsorts/transactions
LetPercentSortOverflows=Sortoverflows*100/Totalsorts
如果PercentSortOverflows超过3%,可能说明应用中有比较严重的sortSQL。因为大量的overflows说明有大量的sort出现,为零或者小于1时比较理想的。
如果有大量的overflow出现,权宜之计是增加SORTHEAP,但是这么做只是隐藏了问题。根本解决是:要定位SQL,通过调整SQL,INDEX,clustering来减少sort代价。
如果SortsPerTX大于5,说明每个交易的sort数目过多,某些应用可能执行了大量的小复合查询,不会overflow,但是有很小的时间段。但是会消耗大量的CPU。同样是要调整SQL,INDEX,clustering来解决问题。
6.TemporaryTablespaces
临时表空间一般要有3个containers在不同的disk上,可以实现并行I/O,提高sorts,hashjoins,或者其他在TEMPSPACE上的动作的性能。
db2"listtablespacesshowdetail",可查看临时表空间的container:
TablespaceID=1
Name=TEMPSPACE1
Type=Systemmanagedspace
Contents=Temporarydata
State=0x0000
Detailedexplanation:Normal
Totalpages=1
Useablepages=1
Usedpages=1
Freepages=Notapplicable
Highwatermark(pages)=Notapplicable
Pagesize(bytes)=4096
Extentsize(pages)=32
Prefetchsize(pages)=96
Numberofcontainers=3
这里表示有3个container,Prefetchsize是Extentsize的3倍。为了最好的并行性能,最好Prefetchsize是Extentsize的倍数。一般倍数是container的数目。
db2"listtablespacecontainersfor1showdetail"
可以看到containers的定义。
7.Locks
缺省的LOCKTIMEOUT=-1,就是说不设置lock的timeout,在OLTP中这可能是一个灾难。我们要设置比较小的数值,比如设置LOCKTIMEOUT=10或者15秒。
查看命令:
db2"getdbcfgforDBNAME",
继续查看下面的信息:
Locktimeout(sec)(LOCKTIMEOUT)=-1
要和应用人员将明白,他们是否已经在程序中可以处理timeout的情况。然后设置:
db2"updatedbcfgforDBNAMEusingLOCKTIMEOUT15"
可以在系统中察看lockwait的数目,lockwaittime,locklist使用的内存量。
db2"getsnapshotfordatabaseonDBNAME"
查看:
Locksheldcurrently=0
Lockwaits=0
Timedatabasewaitedonlocks(ms)=0
Locklistmemoryinuse(Bytes)=576
Deadlocksdetected=0
Lockescalations=0
Exclusivelockescalations=0
Agentscurrentlywaitingonlocks=0
LockTimeouts=0
假如locklist的内存量(bytes)超过LOCKLIST的50%,那么需要增加LOCKLIST的量,LOCKLIST是按4k计算。
8.MaximumOpenFiles
最大的打开文件数目
DB2限制同时打开的文件数目,数据库参数"MAXFILOP"限定了并发打开的文件数目。如达到这个数目,DB2就会开始关闭和打开Tablespace文件,包括rawdevice,这样会降低SQL反映时间和占用CPU。
使用命令来查看是否有文件关闭情况:
db2"getsnapshotfordatabaseonDBNAME"
看看其中的"Databasefilesclosed=0"
如果值不是零,就需要修改MAXFILOP,
db2"updatedbcfgforDBNAMEusingMAXFILOPN"
9.Agents
需要保证有足够的agent应付系统负载。
命令:db2"getsnapshotfordatabasemanager"
此 时需要观察“Agentswaitingforatoken”或者 “Agentsstolenfromanotherapplication”,假如有值,就需要增加DBmanager的agent值,也就 是修改MAXAGENTS和/或者MAX_COORDAGENTS的值。
Highwatermarkforagentsregistered=7
Highwatermarkforagentswaitingforatoken=0
Agentsregistered=7
Agentswaitingforatoken=0
Idleagents=5
Agentsassignedfrompool=158
AgentscreatedfromemptyPool=7
Agentsstolenfromanotherapplication=0
Highwatermarkforcoordinatingagents=7
Maxagentsoverflow=0
10.MonitorSwitches
打开MonitorSwitch后才可以获得性能方面的信息,详细命令如下:
db2"updatemonitorswitchesusinglockONsortONbufferpoolONuowONtableONstatementON"
查看执行计划:
db2expln:
db2expln-ddbname-cpkgOwner-ppkgNmae-oexpln.out
dynexpln:
dynexpln-deos-q"select*fromeosmenu"-g-t
dynexpln-deos-fquery.sql-oout.txt
更新统计信息:
runstats:
db2runstatsontablesongxn.eosmenuandindexssongxn.ix1,songxn.ix2allowreadaccess
db2runstatsontablesongxn.eosmenuwithdistributionanddetailedindexall
调整优化等级:
(0,1,2,3,5,7,9):
更改DFT_QUERYOPT(dbcfg),默认为5
SQL:setcurrentqueryoptimization=3
索引:
建立索引:
createuniqueindexind1onvicky.staff(dept,lastname)
createuniqueindexind2onvicky.emplyee(empno)include(lastname,salary)
include中的字段不列入排序范围
丛集索引:
记录与索引的顺序一致
cretaeindexind3onvicky.staff(dept)CLUSTER
SCANMODE:
IndexScan,FullIndexScan(IndexonlyAccess),RelationScan
查询索引:
selectindnamefromsyscat.indexeswheretabname=’customer’
索引建议器:
db2advis-ddbname-iquery.sql|-s"sqlstmt"-oadvis.out
在数据页中预留空间:
altertablevicky.staffPCTFREE30(预留30%)
loadfromstaff.ixfofixfmodifiedbypagefreespace=30replaceintovicky.staff
缓冲池与IO
默认为IBMDEFAULTBP
新建缓冲池:
db2createbufferpoolbpnamesize1000pagesize4k
altertablespacetbnamebufferpoolbpname
当脏页超过CHNGPGS_THRESH(%,dbcfg)时,缓冲池将被清空并写回
延展缓冲池:
ESTORE_SEG_SZ&NUM_ESTORE_SEGS(dbcfg)
db2alterbufferpoolibmdefaultbp[not]extendedstorage
I/OSERVER:
NUM_IOSERVERS(dbcfg):一般为磁盘数+2
数据重整:
REORGCHK:
db2reorgchkupdatestatisticsontableall该语句也用来对所有表做RUNSTATS
db2reorgchkcurrentstatisticsontablevicky.staff
tablestatistics:
CARD:记录笔数
OV(ERFLOW):overflow的记录数
NP(AGES):含有记录的页数
FP(AGES):表格占用的总页数
TSIZE(Bytes):表格大小
indexstatistics:
LEAF:leafpage数
ELEAF:空叶数
NDEL:被删除的RID数
LVLS:索引层级数
ISIZE:索引平均长度
KEYS:不同的索引值的个数
表格重整:
db2reorgtablevicky.staffindexind1usetempspace2indexscan
索引重整:
db2reorgindexesallfortablevicky.staff_options_
options:allowread|write|noaccess,cleanuponlypages|all(不重建索引结构,只回收空索引页)
联机表格重整(V8+):
db2reorgtablevicky.staffindexvicky.ind2inplaceallowwriteaccess
db2reorgtablevicky.staffindexvicky.ind2inplacepause|resume
db2listhistoryreorgallfordbname
MQT
MQT:
建立MQT:
CREATETABLEvicky.mqt1AS
(SELECTname,location,salary
FROMvicky.staff,vicky.org
WHEREstaff.dept=org.deptnumbANDsalary>20000
)DATAINITIALLYDEFERREDREFRESHDEFERRED|IMMEDIATE
ENABLE|DISABLEQUERYOPTIMIZATION
REFRESHTABLEvicky.mqt1
利用MQT:
RUNSTATSONTABLEvicky.mqt1
UPDATEDBCFGFORsampleUSINGDFT_REFRESH_AGEANY
并行处理
设置并行处理:
UPDATEDBMCFGUSINGINTRA_PARALLELYES
UPDATEDBCFGFOREOSUSINGDFT_DEGREEANY
并行处理上限:
应用级:
SETRUNTIMEDEGREEFOR(25)TO4
SETRUNTIMEDEGREEFORALLTO6
实例级:
UPDATEDBMCFGUSINGMAX_QUERYDEGREE6
MDC表:
CREATETABLEvicky.sales
(YearAndMonthCHAR(4),
RegionCHAR(20),
ProductCHAR(2),
SalesBIGINT
)ORGANIZEBYDIMENSIONS(YearAndMonth,Region)
CREATETABLEvicky.table1
(col1CHAR(10),
col2CHAR(10),
col3CHAR(10),
col4INTEGER,
col5DECIMAL(10,2),
)ORGANIZEBYDIMENSIONS(col1,(col2,col3),col4)