金蝶云星空,系统使用 Tmp 这类临时性质表的一点弊端及改进思路

栏目:云星空知识作者:金蝶来源:金蝶云社区发布:2024-09-23浏览:1

金蝶云星空,系统使用 Tmp 这类临时性质表的一点弊端及改进思路

    

ORACLE 11204

1、金蝶云星空企业版,在运行时,会使用大量的临时表来临时保存数据用做过渡,表名类似:TMPF067C8CE2DCE11EFB6E9000C29D(TMP开头,由数字和字母组成,长度达30位),这样命名只是为了确保表名唯一,用完后很快被删除,最长也不超过24小时就被删掉(被数据库的定时作业清除掉)。

 

2、显然,由于生命周期太短,这类表的数据若有什么特殊属性,数据库的优化器,事先无法预知。事后无法弥补;而恰恰是缺少这类属性,导致优化器,在遇上这类表的一些特殊过滤条件时,无法获取准确的执行计划,影响了执行效率,


如下案例:

 

--2.1、语句的执行耗时情况:跑了34分钟没完成,

上传图片

--2.2、执行计划,可以看出,预估值=10,与实际值13k(至少),是导致语句执行计划不佳的原因,

上传图片

--2.3、引发预估行数和实际行数相差甚远的原因(过滤条件,T0是TMP表的别名)。

上传图片

--2.4、原始语句,

上传图片

--2.5、分析原因,

显然,是源码中的这个条件:T0.FJOINTYPE = 'OUTBILL' AND T0.FTYPE != 'STRAIGHT',让优化器对返回值,做了错误的预判,比如:T0.FJOINTYPE = 'OUTBILL'占表的总行数是0.002,T0.FTYPE != 'STRAIGHT'占表的总行数是0.92,若没有这两列的联合列统计信息,那优化器在计算此条件的返回行数时,会认为是:0.002*0.92=0.00184,但若两字段间的数据存在关系,很可能,满足此条件的实际行数,占总行数的0.5,此时,需要对这两列作联合列的统计信息采集,优化器才能获得较准确的预估值,,,

 

--2.6、分析原因2,

本来,若是普通的业务表,我们可以对这两字段,做联合列的统计信息采集,如下命令:exec dbms_stats.gather_table_stats(user,’表名’,method_opt=>’for columns(FJOINTYPE,FTYPE)’);,采集两字段联合后的统计信息,后续优化器再次遇上此语句时,便能够大致预估出此过滤条件后的行数,,,但由于是临时属性的TMP表,事先不知道表名,无法做有针对性的设置;事后这表又很快被删除,该表不再被使用,因此,优化器无法对它做两字段联合列的统计信息采集,,,

 

--2.7、系统当前对TMP表类型的表,做统计信息采集的策略,

由于TMP表只是一次性使用的临时表,在采集该表的统计信息时,我们采用了对所有字段都采集254桶柱状图的策略,以尽可能提供详尽的统计信息供优化器使用。显然,像上述语句中的这条件,T0.FJOINTYPE = 'OUTBILL' AND T0.FTYPE != 'STRAIGHT',优化器无法预判其会返回多少数据。

 

--2.8、 思考优化、改进策略,

一开始,我建议领域的同事,对原始T0表,执行这过滤条件:T0.FJOINTYPE = 'OUTBILL' AND T0.FTYPE != 'STRAIGHT',得到过滤的数据,生成新的T02表,然后用T02表,替代T0表,执行后续的UPDATE操作。当然,此时的UPDATE语句,要去掉这条件:T0.FJOINTYPE = 'OUTBILL' AND T0.FTYPE != 'STRAIGHT'。

 

但同事表示,原始的T0表中的数据,后续可能会用上,不能在此被排除掉。他提议,可以新增一个TMP表T02,保存这过滤后的数据,然后把这T02添加到语句中,和T0表关联,来过滤T0表中要被UPDATE的数据,也就是,通过T02表的数据,过滤/限制T0表的数据,代码大致如下:

 上传图片


由于是 EXISTS 关联关系,优化器能够准确预估此执行条件后的返回数,可以预见效果将比原先困扰优化器的写法:AND T0.FJOINTYPE = 'OUTBILL' AND T0.FTYPE != 'STRAIGHT',要好得多。若改成MERGE写法,只需要走一遍 WHERE EXISTS,效率会更好,


撰写此文的目的,是想共享此经验,开阔思维。


金蝶云星空,系统使用 Tmp 这类临时性质表的一点弊端及改进思路

ORACLE 112041、金蝶云星空企业版,在运行时,会使用大量的临时表来临时保存数据用做过渡,表名类似:TMPF067C8CE2DCE11EFB6E9000C29D...
点击下载文档
确认删除?
回到顶部
客服QQ
  • 客服QQ点击这里给我发消息