/ 这是我的第208篇文章
达梦干货攻略
【Date:2021.04.28】

MY ARTICLE
GAN HUO
网络情况排查
需要确认网络上是否存在不稳定的因素,因为程序远程访问数据库后,会获取结果,如果网络不稳定,获取结果耗时可能就会出现不稳定的问题,导致程序获取结果集耗时长。此时可以通过ping命令看下网络是否存在丢包问题或者返回时间过长。可以通过在不同机器上的客户端执行相同的语句来进行判断,存在网络问题的服务器上的耗时长,其他机器上耗时短,一般就可判定是网络问题导致。
GAN HUO
计划缓存问题
这个是我们今天关注的重点,数据库默认开启了计划缓存,可以通过如下语句查看是否开启:
select PARA_NAME,PARA_VALUEfrom v$dm_iniwhere para_name like 'USE_PLN_POOL';
该参数设置的为非0,即开启了计划缓存。
参数值解释:
--获取sql的计划缓存select cache_item,sqlstrfrom v$cacheplnwhere sqlstr like '%SQL语句%';
查询到对应的语句的计划缓存信息后,通过如下命令生成语句计划到本地文件:
alter session set events 'immediate trace name plndump level 查出的cache_item,dump_file ''/dbdata/plan0415.log''';
注:其中的文件路径需要单引号引起,由于路径是在外层单引号内,所以使用单引号做了转义,两个单引号代表一个单引号。
根据获取到的计划,我们可以确认计划是否准确,如果计划缓存中的计划存在问题,那后续的SQL在缓存中找到对应的计划后依然使用执行效率不高的计划。如果相关计划一直没有被淘汰,就有可能出现程序执行耗时很长的问题。
那为什么在达梦管理工具中执行时,速度就很快呢?这是因为SQL语句在执行后,在进行计划缓存匹配时,是严格按照执行SQL的字符进行匹配的。数据库会对执行的SQL生成对应的哈希值,SQL语句多一个空格,对于优化器来说都是不同的SQL,这就出现了上述描述的问题。
--清理计划缓存call SP_CLEAR_PLAN_CACHE(cache_item);
清理完毕后,可以通过程序确认对应的操作执行效率是否正常。
例-构造数据:
create table test(c1 int, c2 varchar(100), c3 int, primary key(c1));beginfor i in 1..100000 loopinsert into test values(i, 'aaaaaaa', i);end loop;commit;end;
执行查询语句:
select * from test where c3=3;
查看执行计划缓存
select cache_item,sqlstrfrom v$cacheplnwhere sqlstr like '%select * from test where c3=3%';

生成计划缓存中的执行计划:
alter session set events 'immediate trace name plndump level 848533592,dump_file ''/dbdata/plan0427.log''';
查看生成的文件/dbdata/plan0427.log
DM Database Server x64 V8*** 2021-04-27 16:32:42.803000*** start dump the infos of pln[848533592].start dump the infos of pln[848533592].SQL_STR:select * from test where c3=3;PLN_CMD:0savepoint6dop_try_begin010dop_try_begin014sql 0 024nop26jmp6732nop34push040swap42sloc146err_set 050rollback56jmp6762nop64throw dir167exception end69savepoint75cop 'b'79hlt 0sqlnode[0]::::1 #NSET2: [12, 2500, 64]2 #PRJT2: [12, 2500, 64]; exp_num(4), is_atom(FALSE)3 #SLCT2: [12, 2500, 64];4 #CSCN2: [12, 100000, 64]; INDEX33555613(TEST)end dump the infos of pln[848533592].
在文件中的最后一部分我们可以看到语句实际执行时的执行计划。如果需要手动淘汰该计划,执行如下SQL:
call SP_CLEAR_PLAN_CACHE(848533592);
再次查询计划缓存时,该计划缓存已经淘汰。
GAN HUO
小结
数据库为什么在计划缓存中生成了非最优的计划呢?达梦数据库的优化器是基于代价的优化器,精确的统计信息有助于CBO生成更优的计划,但是统计信息并不会实时更新。所以,统计信息的不准确,就导致CBO生成了非最优的计划。统计信息只有在我们手动更新的时候才会生成,所以当我们发现一些业务表的相关语句存在因为数据的变化而导致语句执行效率差异变大时,我们可以通过设定定时作业对表进行统计信息的收集。
在DM8的新版本中,已经支持了DBMS_STATS. SET_TABLE_PREFS方法,通过开启INI参数AUTO_STAT_OBJ来监控用户表的增删改行数,利用DBMS_STATS系统包中SET_TABLE_PREFS方法对表进行设定,然后利用事件触发器完成自动更新表统计信息的功能。这部分在后面找机会向大家介绍。
往期回顾
END
【内容】:吴聪
【审核】:青城
【编辑】:王





