2023年8月3日发(作者:)

银行核心业务系统数据库SQL优化方法

许威

【摘 要】@@ 对于银行核心业务系统的后台数据库,用户期望有高性能和高可用性的数据平台,这就要求当数据库系统在开发、测试以及上线运行过程中如果出现性能故障时,数据库维护人员能够快速诊断发现并且迅速解决各种复杂问题,以维护系统持续高效运行.

【期刊名称】《中国金融电脑》

【年(卷),期】2011(000)007

【总页数】5页(P50-54)

【作 者】许威

【作者单位】兴业银行股份有限公司福州研发中心

【正文语种】中 文

对于银行核心业务系统的后台数据库,用户期望有高性能和高可用性的数据平台,这就要求当数据库系统在开发、测试以及上线运行过程中如果出现性能故障时,数据库维护人员能够快速诊断发现并且迅速解决各种复杂问题,以维护系统持续高效运行。本文以Informix11.5版本一些新增性能优化的功能为例,针对核心业务系统项目开发过程中遇到的实际案例进行分析,希望能够共同总结出诊断性能问题的思路和方法,从而能够针对具体问题进行常规处理。

一、数据库性能优化的方法 在日常工作中遇到的数据库性能问题优化通常采用以下两种方法。

1.数据库参数调整

观察数据库的运行情况和当前的参数配置值,提出对Informix数据库的参数调整建议方案。通过onstat命令监视、收集数据库运行的情况,从而发现不合理的数据库参数配置。进行全面的数据库健康检查及数据库参数调整的办法可以参考IBM Informix的相关文档。

2.数据库SQL优化

在监测、分析数据库日常运行的情况后,我们发现发生导致系统性能问题的原因通常是由于没有正确创建或使用好索引。数据库管理员可以通过抓取顺序扫描表及对应的SQL、运行效率低的SQL等方法,快速找出有问题的表及SQL,随后运用创建合适索引等方法来解决大量顺序扫描的问题,从而可以大幅度提高数据库的有效处理性能。另一方面,我们也可以考虑从数据库表设计上提高性能,通过找到并删除不必要的垃圾索引,达到节省索引空间,提高insert/delete/update记录效率的目的。

需要注意的是,数据库优化不但是数据库应用项目开发中的重要内容,而且也是一项需要长期不断进行的系统工程,它贯穿于应用开发和产品上线推广的整个生命周期。熟练掌握数据库调优的技能可以让项目中的数据库管理员从项目开发的第一天起就发挥出有效的生产力。

二、SQL调优最佳实践

通过查询数据库的系统表找出应用系统中的大数据表、读写最多的表、消耗时间最长的表、顺序扫描的表和锁等待的表,这是解决数据库性能问题的最关键性的工作。

1.查找顺序扫描的表

顺序扫描/全表扫描可以被定义为读取所有属于该表的数据页,返回所有行。从表的第一个数据页开始,顺序的访问所有包含该表数据页的设备,直到最后一页为止(图 1为进行全表扫描的示例)。

图1 全表扫描示例

对于银行核心这样的OLTP系统来说,在系统中对大表进行全表扫描是一个代价很高的操作,会把不需要的数据页填充到内存缓冲区中,这会占用内存缓冲区的使用并进而影响到数据库的性能。

下面是SQL查询找出自数据库启动以来所有发生过顺序扫描/全表扫描操作的表,以便于进一步分析。

select dbsname,tabname,nrows,seqscans from

(

select e,e::char(20) tabname,,ns

from sysmaster:sysptprof p, $dbname1:systables t

where e=e and e="$dbname1"

and >99 and ns > 0

union all

select e,e::char(20) tabname,,ns

from sysmaster:sysptprof p, $dbname2:systables t

where e=e and e="$dbname2"

and >99 and ns > 0

union all

…)

order by seqscans desc;

需要说明的是,上例中$dbname1,$dbname2代表应用中的数据库名称,和表1中列dbsname相对应,输出结果见表1。表1说明了哪些表进行了多少次顺序扫描,第1列dbsname为表对象所在的数据库名称,第2列tabname为表名称,第3列nrows为表的记录数目,第4列Seqscans为该表发生顺序扫描的次数。从上面的结果中我们需要重点关注扫描次数多或者记录数大的表。在表1中我们找出顺序扫描(sequential scan)次数较多的表。如果被找出的某个表的数据行数较少,则不需要对用到该表的SQL语句进行修改;如果被找出的某个表的数据行数较多,我们需要考虑为该表添加索引以减少该表的顺序扫描次数。

表1 全表扫描输出结果dbsname tabname nrows Seqscans Csk sfcsb 32 1046

Zwk dshqzwj 587¬4423 20 Zwk jywlxxwj 680839 12

2.查找顺序扫描的SQL

为了发现顺序扫描的SQL,我们需要打开SQL 跟踪器(SQL Tracing)。SQL

Tracing是IDS版本11的新功能,用于追踪SQL执行的情况,帮助诊断SQL,包含的信息有以下几个方面:SQL执行的时间、使用的资源情况、等待每一个资源的时间等。默认情况下IDS的SQL Tracing功能是关闭的,我们可以通过在dbaccess中执行命令函数或者Informix Open admin Tool(OAT)图形界面工具来打开该功能。

SQL Tracing功能打开后,SQL相关信息体现在视图sysmaster:syssqltrace中,包括以下信息:操作系统用户ID、用户会话ID、数据库名称、SQL类型、SQL语句的运行时间、SQL语句的执行结束时间、SQL语句或者函数中所包含的内容、其他统计信息及隔离级别。

通常打开SQL tracing的方法有两种办法:一是在dbaccess 中以命令行模式打开;二是使用OAT工具的图形界面方式打开。使用命令函数打开SQL Tracing的步骤如下。

(1)打开SQL 跟踪功能。

database sysadmin;

execute function task ("set sql tracing on",100000,"1k", "low","csk"); execute function task ("set sql tracing on",100000,"1k", "low","fhk");

execute function task ("set sql tracing on",100000,"1k", "low","khk");

若需要跟踪不同的数据库请相应修改数据库名即可,上例保留最近的1万行SQL,同时为每个SQL预留的内存空间为1K。

(2)执行顺序扫描SQL跟踪语句。

(3)关闭跟踪。

execute function task ("set sql tracing off");

我们也可以通过Informx Open Admin Tools进行打开/关闭SQL trace的操作。登录OAT,点击菜单:Performance Analysis->SQL Explorer->Trace state->ON

以下语句能够帮助我们发现存在顺序扫描行为的SQL。

select distinct sql_statement

from sysmaster:Syssqltrace t

inner join sysmaster:syssqltrace_iter i

on _id = _id

where _itr_info='Seq Scan'

order by 1;

执行结果范例输出如下:

SELECT jydqdh,jyjgdh,hbzl,jdbj,zhdh,jyje,zhye,qxrq,cpzxh,cpznxh,cq,sqgy

FROM ZWK:jyzwxxwj

WHERE jydm="9221" and jyrq='2010/12/28' and jlzt='1'

INTO TEMP cpwjt with no log;

通过查看执行计划发现对对ZWK:jyzwxxwj进行全表扫描,而该表记录数较多(记录数达到5304519)。

查看相关的执行计划如下。

QUERY: (OPTIMIZATION TIMESTAMP:05-27-2011 17:59:33)

SELECT jydqdh,jyjgdh,hbzl,jdbj,zhdh,jyje,zhye,qxrq,cpzxh,cpznxh,cq,sqgy

FROM ZWK:jyzwxxwj

WHERE jydm="9221" and jyrq=" 2010/12/28" and jlzt='1'

INTO TEMP cpwjt with no log

Estimated Cost: 598269

Estimated # of Rows Returned: 5273

1) wj: SEQUENTIAL SCAN

Filters: (( = '1' AND = 2010/12/28 ) AND

= '9221' )

通过分析,我们可以考虑在jydm字段上建立索引,这样可以有效提高SQL脚本的处理效率。

3.查找出现锁等待的表

以下是SQL查询出现锁等待的表:

dbaccess sysmaster

select dbsname,tabname,

sum(pf_rqlock) as locks,

sum(pf_wtlock) as lockwaits,

sum(pf_deadlk) as deadlocks

from sysactptnhdr,systabnames

where pf_wtlock > 0

and m = m group by dbsname,tabname

order by lockwaits desc;

输出结果见表2,表2说明了数据库启动后出现锁等待的情况,第1列dbsname为表对象所在的数据库名称,第二2列tabname为表名称,第3列locks为锁发生次数,第4列lockwaits为锁等待次数,第5列deadlocks为该表发生死锁的次数。

表2 出现锁等待的dbsname tabname locks lockwaits deadlocks zfk

fzfbwwjsy1 4837174 429 0 ywk wyplzzhzwj 79180741 181 0 ywk

wyplzfhzwj 7688685 178 0

对于锁等待多的表,我们需要进行重点关注,确保无顺序扫描,去掉不必要的索引,同时采用行级锁。由于产生锁等待的原因有多种,需要具体分析。我们大体上从以下角度进行调整,以减少锁带来的问题。

(1)尽量减少记录被锁的时间窗口,如:合理的表设计,使用行级锁、避免顺序扫描、合理设计和使用索引,以便提高处理性能;

(2)合理使用不同的隔离级别,根据具体的应用场景采用合理的隔离级别,以提高并发性。

4.删除多余的索引

假设系统中有大量多余的索引,通过删除多余的索引可以提高记录增删改的性能,同时节省大量不必要的存储空间。

通过分析表中相应的索引,找到多余的索引,常见的情况如已经创建了一个复合索引,但同时又创建了单字段的独立索引。另外需要考虑合并多个单独的索引成为一个复合索引的场景。以下SQL语句帮助我们发现应用系统中冗余的索引。

select dbsname, e, indexname, ,(isreads + pagreads)

diskreads, (iswrites + pagwrites) diskwrites

from sysmaster:sysptprof a, $dbname1:systables b,$dbname1:sysfragments

c

where = and m=

and isreads+pagreads=0

and >99

union all

select dbsname, e, indexname, ,(isreads + pagreads)

diskreads, (iswrites + pagwrites)

diskwrites

from sysmaster:sysptprof a, $dbname1:systables b,$dbname2:sysfragments

c

where = and m=

and isreads+pagreads=0

and >99

union all

需要说明的是,上例中$dbname1,$dbname2代表应用中的数据库名称,和表3中列dbsname相对应,输出结果见表3。表3说明了系统中被访问次数为0的索引,第1列dbsname为表对象所在的数据库名称,第2列tabname为表名称,第三3列indexname为索引名称,第4列nrows为表中记录数,第5列diskreads为该表在内存和磁盘中数据被访问的次数,第6列diskwrites为该表数据被写入内存和磁盘中的次数。如果diskreads列为0,说明该索引对象自数据库系统启动以来从未被访问,可以考虑被删除。 表3 系统中被访问次数为0的索引dbsname tabname indexname nrows

diskreads diskwrites csk llb llbsy1 1488885 0 0 khk xjzhdzb xjzhdzbsy1

1252672 0 0 khk xjzhdzb xjzhdzbsy2 1252672 0 0

5.查找运行最慢的SQL语句

当数据库系统繁忙时,一般消耗系统资源的都集中在几个运行最慢的SQL上,我们通过找到当前数据库上耗时最长的SQL,然后进行针对性的优化,往往能够快速找到系统的瓶颈,进而解决系统的性能问题。

表4 运行时间最长的SQL语句sql_sid sql_uid finishtime sql_runtime

sql_actualrows sql_statement 352039 203 2011-6-2 16:02 55.2903272 Sec

523684 insert into tmp1265a select a . jydm , a . jzjydm ,a . jydqdh , a .

jyjgdh , a . jygy , a . zhdh , a .jdbj , a . jyje , a . zhye , a . pzdh , a . jyrq , a.

jysj , a . cpzxh , a . gylsh , a . zydh , a . djbbj, a . bczbz , a . cbbz , a . jlzt , a .

hxjylsbh from zwk : jyzwxxwj a where a . zhdh in ( select zhdh from ywk :

jszxdjgxb b where b . jlzt = '1' )210104 203 2011-6-2 16:01 47.1632846 Sec

1 select xh from csk : xhb where xhzl = ? and jlzt ='1' for update of xh

打开SQL tracing,过一段时间后执行如下SQL语句:

SELECT sql_sid, sql_uid,

dbinfo('UTC_TO_DATETIME',sql_finishtime) as finishtime,

TRUNC(_runtime,7) || ' Sec' AS sql_runtime,

sql_actualrows, sql_statement

FROM sysmaster:syssqltrace a, (select first 2 sql_id from

sysmaster:syssqltrace

where sql_runtime > 0 order by sql_runtime desc) b where

_id=_id; 表4为运行时间最长的SQL语句。表4说明数据库系统启动后在系统中运行时间排名前两位的SQL语句,第1列sql_sid为SQL语句编号,第2列sql_uid为执行SQL语句的用户编号,第3列finishtime为SQL语句的完成时间,第4列sql_runtime为SQL语句的执行时间,第5列sql_actualrows为返回的记录数,第6列sql_statment为SQL语句包含的内容。

在开发或者生产环境中,我们可能会经常遇到某些硬件资源如CPU或者内存被过度使用而影响系统性能或者正常运行的问题。大多数情况下,系统的性能问题都是由不良的SQL代码引起的。在开发环境中,由于数据量较少,难以体现出SQL查询语句的性能差异,但是在生产环境中,随着真实数据量的增加,大量并发访问,系统的响应速度可能成为最需要解决的问题。针对这类现象,本文提出了几种最常用的方法用于系统性能优化,帮助我们诊断发现潜在的数据库性能问题,进而提出数据库系统调整的建议,使我们可以识别存在的问题和隐患,提升核心业务系统的处理能力,优化核心业务系统数据库性能,满足各项业务发展需要,从而保障业务稳定安全开展。

2023年8月3日发(作者:)

银行核心业务系统数据库SQL优化方法

许威

【摘 要】@@ 对于银行核心业务系统的后台数据库,用户期望有高性能和高可用性的数据平台,这就要求当数据库系统在开发、测试以及上线运行过程中如果出现性能故障时,数据库维护人员能够快速诊断发现并且迅速解决各种复杂问题,以维护系统持续高效运行.

【期刊名称】《中国金融电脑》

【年(卷),期】2011(000)007

【总页数】5页(P50-54)

【作 者】许威

【作者单位】兴业银行股份有限公司福州研发中心

【正文语种】中 文

对于银行核心业务系统的后台数据库,用户期望有高性能和高可用性的数据平台,这就要求当数据库系统在开发、测试以及上线运行过程中如果出现性能故障时,数据库维护人员能够快速诊断发现并且迅速解决各种复杂问题,以维护系统持续高效运行。本文以Informix11.5版本一些新增性能优化的功能为例,针对核心业务系统项目开发过程中遇到的实际案例进行分析,希望能够共同总结出诊断性能问题的思路和方法,从而能够针对具体问题进行常规处理。

一、数据库性能优化的方法 在日常工作中遇到的数据库性能问题优化通常采用以下两种方法。

1.数据库参数调整

观察数据库的运行情况和当前的参数配置值,提出对Informix数据库的参数调整建议方案。通过onstat命令监视、收集数据库运行的情况,从而发现不合理的数据库参数配置。进行全面的数据库健康检查及数据库参数调整的办法可以参考IBM Informix的相关文档。

2.数据库SQL优化

在监测、分析数据库日常运行的情况后,我们发现发生导致系统性能问题的原因通常是由于没有正确创建或使用好索引。数据库管理员可以通过抓取顺序扫描表及对应的SQL、运行效率低的SQL等方法,快速找出有问题的表及SQL,随后运用创建合适索引等方法来解决大量顺序扫描的问题,从而可以大幅度提高数据库的有效处理性能。另一方面,我们也可以考虑从数据库表设计上提高性能,通过找到并删除不必要的垃圾索引,达到节省索引空间,提高insert/delete/update记录效率的目的。

需要注意的是,数据库优化不但是数据库应用项目开发中的重要内容,而且也是一项需要长期不断进行的系统工程,它贯穿于应用开发和产品上线推广的整个生命周期。熟练掌握数据库调优的技能可以让项目中的数据库管理员从项目开发的第一天起就发挥出有效的生产力。

二、SQL调优最佳实践

通过查询数据库的系统表找出应用系统中的大数据表、读写最多的表、消耗时间最长的表、顺序扫描的表和锁等待的表,这是解决数据库性能问题的最关键性的工作。

1.查找顺序扫描的表

顺序扫描/全表扫描可以被定义为读取所有属于该表的数据页,返回所有行。从表的第一个数据页开始,顺序的访问所有包含该表数据页的设备,直到最后一页为止(图 1为进行全表扫描的示例)。

图1 全表扫描示例

对于银行核心这样的OLTP系统来说,在系统中对大表进行全表扫描是一个代价很高的操作,会把不需要的数据页填充到内存缓冲区中,这会占用内存缓冲区的使用并进而影响到数据库的性能。

下面是SQL查询找出自数据库启动以来所有发生过顺序扫描/全表扫描操作的表,以便于进一步分析。

select dbsname,tabname,nrows,seqscans from

(

select e,e::char(20) tabname,,ns

from sysmaster:sysptprof p, $dbname1:systables t

where e=e and e="$dbname1"

and >99 and ns > 0

union all

select e,e::char(20) tabname,,ns

from sysmaster:sysptprof p, $dbname2:systables t

where e=e and e="$dbname2"

and >99 and ns > 0

union all

…)

order by seqscans desc;

需要说明的是,上例中$dbname1,$dbname2代表应用中的数据库名称,和表1中列dbsname相对应,输出结果见表1。表1说明了哪些表进行了多少次顺序扫描,第1列dbsname为表对象所在的数据库名称,第2列tabname为表名称,第3列nrows为表的记录数目,第4列Seqscans为该表发生顺序扫描的次数。从上面的结果中我们需要重点关注扫描次数多或者记录数大的表。在表1中我们找出顺序扫描(sequential scan)次数较多的表。如果被找出的某个表的数据行数较少,则不需要对用到该表的SQL语句进行修改;如果被找出的某个表的数据行数较多,我们需要考虑为该表添加索引以减少该表的顺序扫描次数。

表1 全表扫描输出结果dbsname tabname nrows Seqscans Csk sfcsb 32 1046

Zwk dshqzwj 587¬4423 20 Zwk jywlxxwj 680839 12

2.查找顺序扫描的SQL

为了发现顺序扫描的SQL,我们需要打开SQL 跟踪器(SQL Tracing)。SQL

Tracing是IDS版本11的新功能,用于追踪SQL执行的情况,帮助诊断SQL,包含的信息有以下几个方面:SQL执行的时间、使用的资源情况、等待每一个资源的时间等。默认情况下IDS的SQL Tracing功能是关闭的,我们可以通过在dbaccess中执行命令函数或者Informix Open admin Tool(OAT)图形界面工具来打开该功能。

SQL Tracing功能打开后,SQL相关信息体现在视图sysmaster:syssqltrace中,包括以下信息:操作系统用户ID、用户会话ID、数据库名称、SQL类型、SQL语句的运行时间、SQL语句的执行结束时间、SQL语句或者函数中所包含的内容、其他统计信息及隔离级别。

通常打开SQL tracing的方法有两种办法:一是在dbaccess 中以命令行模式打开;二是使用OAT工具的图形界面方式打开。使用命令函数打开SQL Tracing的步骤如下。

(1)打开SQL 跟踪功能。

database sysadmin;

execute function task ("set sql tracing on",100000,"1k", "low","csk"); execute function task ("set sql tracing on",100000,"1k", "low","fhk");

execute function task ("set sql tracing on",100000,"1k", "low","khk");

若需要跟踪不同的数据库请相应修改数据库名即可,上例保留最近的1万行SQL,同时为每个SQL预留的内存空间为1K。

(2)执行顺序扫描SQL跟踪语句。

(3)关闭跟踪。

execute function task ("set sql tracing off");

我们也可以通过Informx Open Admin Tools进行打开/关闭SQL trace的操作。登录OAT,点击菜单:Performance Analysis->SQL Explorer->Trace state->ON

以下语句能够帮助我们发现存在顺序扫描行为的SQL。

select distinct sql_statement

from sysmaster:Syssqltrace t

inner join sysmaster:syssqltrace_iter i

on _id = _id

where _itr_info='Seq Scan'

order by 1;

执行结果范例输出如下:

SELECT jydqdh,jyjgdh,hbzl,jdbj,zhdh,jyje,zhye,qxrq,cpzxh,cpznxh,cq,sqgy

FROM ZWK:jyzwxxwj

WHERE jydm="9221" and jyrq='2010/12/28' and jlzt='1'

INTO TEMP cpwjt with no log;

通过查看执行计划发现对对ZWK:jyzwxxwj进行全表扫描,而该表记录数较多(记录数达到5304519)。

查看相关的执行计划如下。

QUERY: (OPTIMIZATION TIMESTAMP:05-27-2011 17:59:33)

SELECT jydqdh,jyjgdh,hbzl,jdbj,zhdh,jyje,zhye,qxrq,cpzxh,cpznxh,cq,sqgy

FROM ZWK:jyzwxxwj

WHERE jydm="9221" and jyrq=" 2010/12/28" and jlzt='1'

INTO TEMP cpwjt with no log

Estimated Cost: 598269

Estimated # of Rows Returned: 5273

1) wj: SEQUENTIAL SCAN

Filters: (( = '1' AND = 2010/12/28 ) AND

= '9221' )

通过分析,我们可以考虑在jydm字段上建立索引,这样可以有效提高SQL脚本的处理效率。

3.查找出现锁等待的表

以下是SQL查询出现锁等待的表:

dbaccess sysmaster

select dbsname,tabname,

sum(pf_rqlock) as locks,

sum(pf_wtlock) as lockwaits,

sum(pf_deadlk) as deadlocks

from sysactptnhdr,systabnames

where pf_wtlock > 0

and m = m group by dbsname,tabname

order by lockwaits desc;

输出结果见表2,表2说明了数据库启动后出现锁等待的情况,第1列dbsname为表对象所在的数据库名称,第二2列tabname为表名称,第3列locks为锁发生次数,第4列lockwaits为锁等待次数,第5列deadlocks为该表发生死锁的次数。

表2 出现锁等待的dbsname tabname locks lockwaits deadlocks zfk

fzfbwwjsy1 4837174 429 0 ywk wyplzzhzwj 79180741 181 0 ywk

wyplzfhzwj 7688685 178 0

对于锁等待多的表,我们需要进行重点关注,确保无顺序扫描,去掉不必要的索引,同时采用行级锁。由于产生锁等待的原因有多种,需要具体分析。我们大体上从以下角度进行调整,以减少锁带来的问题。

(1)尽量减少记录被锁的时间窗口,如:合理的表设计,使用行级锁、避免顺序扫描、合理设计和使用索引,以便提高处理性能;

(2)合理使用不同的隔离级别,根据具体的应用场景采用合理的隔离级别,以提高并发性。

4.删除多余的索引

假设系统中有大量多余的索引,通过删除多余的索引可以提高记录增删改的性能,同时节省大量不必要的存储空间。

通过分析表中相应的索引,找到多余的索引,常见的情况如已经创建了一个复合索引,但同时又创建了单字段的独立索引。另外需要考虑合并多个单独的索引成为一个复合索引的场景。以下SQL语句帮助我们发现应用系统中冗余的索引。

select dbsname, e, indexname, ,(isreads + pagreads)

diskreads, (iswrites + pagwrites) diskwrites

from sysmaster:sysptprof a, $dbname1:systables b,$dbname1:sysfragments

c

where = and m=

and isreads+pagreads=0

and >99

union all

select dbsname, e, indexname, ,(isreads + pagreads)

diskreads, (iswrites + pagwrites)

diskwrites

from sysmaster:sysptprof a, $dbname1:systables b,$dbname2:sysfragments

c

where = and m=

and isreads+pagreads=0

and >99

union all

需要说明的是,上例中$dbname1,$dbname2代表应用中的数据库名称,和表3中列dbsname相对应,输出结果见表3。表3说明了系统中被访问次数为0的索引,第1列dbsname为表对象所在的数据库名称,第2列tabname为表名称,第三3列indexname为索引名称,第4列nrows为表中记录数,第5列diskreads为该表在内存和磁盘中数据被访问的次数,第6列diskwrites为该表数据被写入内存和磁盘中的次数。如果diskreads列为0,说明该索引对象自数据库系统启动以来从未被访问,可以考虑被删除。 表3 系统中被访问次数为0的索引dbsname tabname indexname nrows

diskreads diskwrites csk llb llbsy1 1488885 0 0 khk xjzhdzb xjzhdzbsy1

1252672 0 0 khk xjzhdzb xjzhdzbsy2 1252672 0 0

5.查找运行最慢的SQL语句

当数据库系统繁忙时,一般消耗系统资源的都集中在几个运行最慢的SQL上,我们通过找到当前数据库上耗时最长的SQL,然后进行针对性的优化,往往能够快速找到系统的瓶颈,进而解决系统的性能问题。

表4 运行时间最长的SQL语句sql_sid sql_uid finishtime sql_runtime

sql_actualrows sql_statement 352039 203 2011-6-2 16:02 55.2903272 Sec

523684 insert into tmp1265a select a . jydm , a . jzjydm ,a . jydqdh , a .

jyjgdh , a . jygy , a . zhdh , a .jdbj , a . jyje , a . zhye , a . pzdh , a . jyrq , a.

jysj , a . cpzxh , a . gylsh , a . zydh , a . djbbj, a . bczbz , a . cbbz , a . jlzt , a .

hxjylsbh from zwk : jyzwxxwj a where a . zhdh in ( select zhdh from ywk :

jszxdjgxb b where b . jlzt = '1' )210104 203 2011-6-2 16:01 47.1632846 Sec

1 select xh from csk : xhb where xhzl = ? and jlzt ='1' for update of xh

打开SQL tracing,过一段时间后执行如下SQL语句:

SELECT sql_sid, sql_uid,

dbinfo('UTC_TO_DATETIME',sql_finishtime) as finishtime,

TRUNC(_runtime,7) || ' Sec' AS sql_runtime,

sql_actualrows, sql_statement

FROM sysmaster:syssqltrace a, (select first 2 sql_id from

sysmaster:syssqltrace

where sql_runtime > 0 order by sql_runtime desc) b where

_id=_id; 表4为运行时间最长的SQL语句。表4说明数据库系统启动后在系统中运行时间排名前两位的SQL语句,第1列sql_sid为SQL语句编号,第2列sql_uid为执行SQL语句的用户编号,第3列finishtime为SQL语句的完成时间,第4列sql_runtime为SQL语句的执行时间,第5列sql_actualrows为返回的记录数,第6列sql_statment为SQL语句包含的内容。

在开发或者生产环境中,我们可能会经常遇到某些硬件资源如CPU或者内存被过度使用而影响系统性能或者正常运行的问题。大多数情况下,系统的性能问题都是由不良的SQL代码引起的。在开发环境中,由于数据量较少,难以体现出SQL查询语句的性能差异,但是在生产环境中,随着真实数据量的增加,大量并发访问,系统的响应速度可能成为最需要解决的问题。针对这类现象,本文提出了几种最常用的方法用于系统性能优化,帮助我们诊断发现潜在的数据库性能问题,进而提出数据库系统调整的建议,使我们可以识别存在的问题和隐患,提升核心业务系统的处理能力,优化核心业务系统数据库性能,满足各项业务发展需要,从而保障业务稳定安全开展。