1、性能调优概述
性能问题的症状
响应时间慢
吞吐量低
资源占用高(CPU、Memory、I/0等)
数据库角度
数据库逻辑设计
数据库物理设计(存储规划)
SQL语句
数据库调优关键
I/O最关键
减少I/O
最大化I/O效率
存储规律,物理设计
CPU两个杀手
表扫描
排序
Memory命中率可能会骗人
SQL是一切问题的根源
2、性能调优步骤
明确问题->收集数据->分析数据->细化、定位问题->优化
3、DB2数据库监控工具-db2pd
3.1、监控工具总结
即时监控工具
Snapshot
db2pd
db2top
事件监控工具
Event monitor
新事件监控工具
对数据的访问是通过SQL语句执行的,绝大数性能问题都是SQL本身问题
动态语句:JDBC、DB2命令行
静态语句:存储过程、嵌入式SQL程序
3.2、db2pd命令工具
3.2.1 db2pd介绍
用于监控和DB2疑难分析
非***式工具,对DB2的性能影响小
在 8.2 版中, 引入一种新的工具 db2pd 来监控和管理 DB2 数据库和实例。使用这一工具可以跟踪事务、表空间、表统计信息、动态 SQL 和所有配置信息。对于故障检修、确定问题和性能调优等方面。
db2pd用于收集 DB2 实例和数据库的统计信息。db2pd 提供了 20 多个选项显示关于数据库事务、表空间、表统计信息、动态 SQL、数据库配置和其他很多细节的信息。单个 db2pd 命令可以检索多个领域的信息,并把结果保存到文件中。也可以在特定时期内调用该工具一定的次数,帮助您了解随着时间的变化数据库中的变动情况。该工具可用于故障检修、问题确定、数据库监控、性能调优和帮助应用程序的开发设
3.2.2、db2pd基本应用
格式: db2pd -d dbname-options
选项:
-applications -agents -transactions -bufferpools -logs
-locks -tablespaces -dynamic -static -fcm
-mempools -memsets -dbmcfg -dbcfg -catalogcache
-sysplex -tcbstats -reorg -recovery -repot -osinfo
db2pd有22个选项,如果想对所有分区,所有活动数据库,运行所有选项,您只要输入db2pd-everything,就会列出所有信息
3.2.3、db2pd选项解析
如果想控制输出的范围,可以参考如下:
-ins 输出实例相关信息
-db dbname 输出数据库dbname相关信息,用于单一指定的数据库。
-alldb 输出所有数据库信息。
-dbppartitionnum 输出特定的数据库分区服务器的信息
-alldbp 输出所有数据库分区服务器的信息
-osinfo 输出操作系统相关信息
实例范围的选项:
(1)-agents
输出DB2代理的相关信息。在日常监控中是一个比较常用的选项,执行方式和输出方式可以通过不同了选项进行控制
db2pd -agentsdb=db2db
只输出数据库DB2DB相关信息。相关子选项还包括agent=<agentid>,application=<appid>等。
(2)-fcm FCM信息
(3)-mempools 输出内存池相关信息
(4)-dbmcfg 输出dbm配置信息,等同于get dbm cfg 命令,但输出格式稍有不同。
(5)-utilities 输出db2实用程序相关信息。如果正在进行数据库备份
数据库范围的选项,注意,数据库范围的选项一定要指定某个数据库,加上参数-db dbname
(1)-applications 特定数据库的应用程序的相关信息。
[db2inst1@localhost ~]$ db2pd -applications-db db2db
同时还有很多相关子选项用于更精确的输出某个应用程序的相关信息。
(2)-transactions 输出某个特定数据库的事务信息
(3)-bufferpools 输出某个特定数据库的缓冲池信息
(4)-logs 输出某个特定数据库的日志信息
(5)-reorgs 输出某个特定数据库的表重组信息
其它用途选项:
(1)-repeat [numsec] [count] 该选项用于重复db2pd命令,并指定间隔多长时间执行多少次,例如:
[db2inst1@localhost ~]$ db2pd -agents -repeat2 5
该命令表明输出实例的代理进程信息,并且是每2秒种输出一次,共输出5次。
(2)-file<filename> 该选项将输出结果保存到一个指定文件中。例如:
[db2inst1@localhost ~]$ db2pd-agents -repeat 2 5 -file agent_info.txt
(3)db2pd 命令的所有选项都可以使用前三个字符的缩写,只有两个除外:-mempools 和–memsets。
接下来讲一个具体应用db2pd的例子。
如果想确定谁给数据库加了锁,并想知道销类型等相关信息:
[db2inst1@localhost ~]$ db2pd-db db2db -lock -transactions -agents -file lock_info.txt
该命令会将lock,transactions,agents三项的输出保存到lock_info.txt中。然后通过lock部分输出中TranHdl可以在transactions输出中找到AppHandl,然后再根据AppHandl,可以在agents部分输出中
找到持有该锁的Userid。在确定是谁给数据库加了锁。
要想了解db2pd命令的全部信息,可以执行db2pd -help来获得。
使用实例:
1.sh /tmp/20141103/test.sh 生成app.txt
2.db2pd -d nns -dyn > dyn.txt
3.根据app.txt中 L-AnchIdL-StmtUID中的值搜索 dyn.txt
定位sql 搜索时四个空格
4、数据库快照分析
4.1 快照信息解析
数据库快照包含一些统计信息、状态信息等,通过db2 get snapshotfor database on nns 或sysibmadm.snapdb
数据库连接和代理信息
锁相关信息:死锁、锁等、锁超时、锁升级信息
排序信息:排序溢出、排序时间
缓冲池信息:同步、异步逻辑/物理读/写、命中率
事务信息:提交/回滚的事务数
SQL语句信息:动态、静态SQL语句; Select/UDI SQL:增删改查的行数
日志信息:日志空间、最早的事务
Package cache命中率
Catalog cache命中率
4.2、重要快照信息种类
4.2.1、应用快照
db2 get snapshot forapplications on nns
db2 get snapshot forapplications agentid appl-handler
注明:appl-handler可以从list applications的输出中得到
或者
select * fromsysibmadm.snapdb
select * fromsysibmadm.snapappl_info
获取应用执行情况,找到异常应用
查看当前并发应用
db2 list applications
db2 list applications showdetail
db2 list applications fornns [show detail]
4.2.2、表快照
db2 get snapshot for tableson nns
或者
select * fromsysibmadm.snaptab
读取表的读取行数,跟踪热表
4.2.3、动态sql快照
db2 get snapshot for dynamicsql on nns
或者
select * fromsysibmadm.snapdyn_sql
获取动态SQL的语句的执行情况,如执行次数、执行时间、CPU时间、排序、锁等信息。
5、关键性能指标(KPI)
5.1 指标性能总括
读有效性:rows_read/rows_selected
同步读百分比:数据、索引读的效率
表的读写效率
Bufferpool命中率
......
5.2、读有效性
rows_read/rows_selected
读有效性表示每获取一条记录需要访问的行
对于OLTP,最好小于20
对于OLAP,最好小于100
selectROWS_READ/(ROWS_SELECTED+1) as rows_read_effi from sysibmadm.snapdb orders byrows_read_effi
当读有效值比较高时,表示可能在发生表扫描,可通过索引等手段进行优化。
5.3、同步读百分比
数据从存储加载到bufferpool有同步和异步两种方式
同步(synchronousI/O):当有合适的索引时,db2会使用同步I/O访问需要的索引和数据页
异步(AsynchronousI/O):当没有合适的索引时,或SQL语句不够优化时,db2使用异步存取(prefetch)I/O扫描数据或索引
同步读百分比=
100-100*(Asynchronous pooldata pages reads + Asynchronous pool index page reads)/ (Buffer pool dataphysical reads + Buffer pool index reads + 1)
对于交易系统,同步I/O的百分比越高越好,反之则需要优化。
5.4、I/O读写
找到I/O读写频繁的表
Sysibmadm.snaptab
select substr(tabname,1,20)as tabname,rows_read,rows_written from sysibmadm.snaptab order by rows_readdesc
db2pd -tcbstat 查找表扫描较多的表
6、动态语句
找到最差的dynamic SQL语句
通过Sysibmadm.snapdyn_sql视图,扎到如下字段进行排序,扎到最差的SQL
ROWS_READ
ROWS_WRITTEN
NUM_EXCUTIONS
NUM_COMPILATIONS
STMT_SORTS
TOTAL_EXEC_TIME
TOTAL_SYS_CPU_TIME
TOTAL_USER_CPU_TIME
STMT_TEXT
6.1、查看运行时间最长的SQL语句
db2 "selectnum_executions as "Num Execs",average_execution_time_s as "AvgTime(sec)",stmt_sorts as "Num Sorts",sorts_per_execution as"Sorts Per Stmt",substr(stmt_text,1,35) as "SQL Stmt" from sysibmadm.top_dynamic_sql wherenum_executions > 0 order by 2 desc fetch first 10 rows only"
6.2、平均执行时间最长的SQL语句
db2 "select substr(stmt_text,1,500) as stmt_text,average_execution_time_s,num_executionsfrom sysibmadm.top_dynamic_sql orderby average_execution_time_s desc fetch first 10 rows only"|grep -ivselected
6.3、读取行数最多的SQL语句
db2 "select substr(stmt_text,1,500)as stmt_text,NUM_EXECUTIONS,ROWS_READ,ROWS_WRITTEN,STMT_SORTS,SORT_OVERFLOWS ,TOTAL_SORT_TIME,TOTAL_USR_CPU_TIME,TOTAL_EXEC_TIMEfrom sysibmadm.snapdyn_sql order by ROWS_READdesc fetch first 10 rows only"|grep -iv selected
6.4、执行次数最多的SQL语句
db2 "select substr(stmt_text,1,500)as stmt_text,NUM_EXECUTIONS,TOTAL_USR_CPU_TIME,TOTAL_EXEC_TIME,SORT_OVERFLOWSfrom sysibmadm.snapdyn_sql order by NUM_EXECUTIONS desc fetch first 10 rowsonly"|grep -iv selected
6.5、排序最多的SQL语句
db2 "selectsubstr(stmt_text,1,500) as stmt_text,stmt_sorts,SORT_OVERFLOWS,TOTAL_USR_CPU_TIME,NUM_EXECUTIONSfrom sysibmadm.snapdyn_sql order bystmt_sorts desc fetch first 10 rows only"|grep -iv selected
6.6、DB2 V9新特性——重点TOP_DYNAMIC_SQL
和oracle的top sql对应的是sysibmadm.top_dynamic_sql,以下的视图所在的模式都是sysibmadm
使用快照管理视图来标识高成本应用程序
ShopMart 数据库上最近的工作负载增长已开始影响到整体数据库性能。Jessie 是 ShopMart 的 DBA,她尝试使用下列管理视图来标识日常工作负载中较大的资源使用者:
6.6.1、APPLICATION_PERFORMANCE读取的行数
此视图帮助 Jessie 标识可能正在执行大型表扫描操作的应用程序:
connect to shopmart;
select AGENT_ID, ROWS_SELECTED, ROWS_READ from APPLICATION_PERFORMANCE;
ROWS_SELECTED 值显示返回给应用程序的行数,ROWS_READ 值显示在基本表中访问的行数。如果选择率很低,则表示该应用程序可能正在执行表扫描操作,通过创建索引可以避免应用程序执行该操作。Jessie 使用此视图来标识可能有问题的查询,然后,她可以进行进一步调查,即查看 SQL 以确定是否能够减少查询在执行时读取的行数。
6.6.2、LONG_RUNNING_SQL 执行的运行时间
Jessie 使用 LONG_RUNNING_SQL 管理视图来标识当前正在执行的运行时间最长的查询:
connect to shopmart;
select ELAPSED_TIME_MIN, APPL_STATUS, AGENT_ID from long_running_sql
order by ELAPSED_TIME_MIN desc fetch first 5 rows only;
通过使用此视图,她可以确定这些查询已运行的时间长度以及这些查询的状态。如果某个查询已执行了很长时间并且正在等待锁,她就可以使用对特定代理程序标识执行查询的 LOCKWAITS 或 LOCK_HELD 管理视图来进行进一步调查。LONG_RUNNING_SQL 视图还会指出正在执行的语句并允许她标识可能有问题的 SQL。
6.6.3、QUERY_PREP_COST运行频率和平均执行时间
Jessie 使用 QUERY_PREP_COST 来对已确定有问题的查询进行故障诊断。此视图可以指出查询的运行频率以及这些查询中每个查询的平均执行时间:
connect to shopmart;
select NUM_EXECUTIONS, AVERAGE_EXECUTION_TIME_S, PREP_TIME_PERCENT from
QUERY_PREP_COST order by NUM_EXECUTIONS desc;
PREP_TIME_PERCENT 值向 Jessie 指出准备查询时耗用的时间在查询执行时间中所占的百分比。如果编译和优化查询时耗用的时间几乎与查询的执行时间一样长,那么,Jessie 可以建议该查询的所有者更改用于该查询的优化类。降低优化类可以使该查询更快地完成优化,从而更快地返回结果。但是,如果某个查询需要相当长的时间来进行准备,但要执行数千次(而不必再次进行准备),则更改优化类并不能提高查询性能。
6.6.4、TOP_DYNAMIC_SQL 执行频率运行时间排序次数
Jessie 使用 TOP_DYNAMIC_SQL 视图来标识执行频率最高、运行时间最长和排序次数最多的动态 SQL 语句。有了此信息,Jessie 在进行 SQL 调整工作时就可以把注意力放在代表某些最大资源使用者的查询上
为了标识运行频率最高的动态 SQL 语句,Jessie 发出以下语句:
connect to shopmart;
select * from TOP_DYNAMIC_SQL order by NUM_EXECUTIONS
desc fetch first 5 rows only;
此语句返回执行频率最高的 5 个动态 SQL 语句的所有执行时间、排序执行次数和语句文本详细信息。
为了标识执行时间最长的动态 SQL 语句,Jessie 检查AVERAGE_EXECUTION_TIME_S 值最大的 5 个查询:
connect to shopmart;
select * from TOP_DYNAMIC_SQL order by AVERAGE_EXECUTION_TIME_S
desc fetch first 5 rows only;
为了查看排序次数最多的动态 SQL 语句的详细信息,Jessie 发出以下语句:
connect to shopmart;
select STMT_SORTS, SORTS_PER_EXECUTION, substr(STMT_TEXT,1,60) asSTMT_TEXT
from TOP_DYNAMIC_SQL order by STMT_SORTS desc fetch first 5 rows only;
7、静态语句
通过database snapshot,staticstatement attemptd表示有静态语句执行
$db2pd -d sample -static
每个存储过程或嵌入式c在内部都是一个package,每条语句都是Package里的section,可通过syscat.statement查找
select substr(pkgname,1,20) as pkgname,substr(text,1,100) as text fromsyscat.statements where pkgnamae=’P9134667’
MON_GET_PKG_CACHE_STMT存储过程返回当前packagecache里的动态语句和静态语句
SELECT MEMBER,SECTION_TYPE,TOTAL_CPU_TIME/NUM_EXEC_WITH_METRICS AS AVG_CPU_TIME,substr(stmt_text,1,50)from TABLE(MON_GET_PKG_CACHE_STMT(NULL,NULL,NULL,-2) as T WHERET.NUM_EXEC_WITH_METRICS <> 0 order by AVG_CPU_TIME