为提高效率,提问时请提供以下信息,问题描述清晰可优先响应。
【DM版本】:dm8
【操作系统】:linux
【问题描述】*:相同的SQL在测试环境上运行很快,在生产环境上运行很慢。 看了执行计划,也不一样。不知道为什么。所有表的索引都是一样的。
请大佬帮忙分析。 生产环境是国产服务器,也是海光cpu,X86系列的服务器,麒麟操作系统。测试环境是联想服务器。 是不是跟DM版本有关系?
SQL:
select sys_guid() sysguid, a.accountType,
nvl(a.realamount,0) + nvl(a.deferaccr,0) amount,b.balance,
b.bldno,b.houseprop,b.housetype,'' corpNo,c.adminno,c.admintype,
b.datafrom,b.orginno,b.dataexplain,'' remark, e.subAccount,
f.regionNo
from (select * from dep_reqlist where reqNo ='11012150000195') a ,arc_houseinfo b,dep_reqinfo c,
(select * from arc_ownerinfo where state in('0','7','8'))e,arc_bldInfo f
where a.houseguid = b.sysguid and a.reqno = c.reqno and case when b.mainhouseguid is not null then b.mainhouseguid
else b.sysguid end = e.houseguid(+) and b.bldno = f.bldno;
测试环境执行计划:
生产环境执行计划:
达梦优化器是基于代价的(CBO),数据量和数据的分布差异都会导致计划偏差,可以对表的统计信息进行收集后,再看执行计划,在统计信息不准或者计划非最优的情况下,也可以通过hint调到预期的计划上,固定计划。
以上案例可以试下hint提示/+ order(a,b,f)/
统计信息的收集:
--收集指定用户下某表统计信息:
call DBMS_STATS.GATHER_TABLE_STATS('username','table_name',null,100,TRUE,'FOR ALL COLUMNS SIZE AUTO');
--收集单个索引统计信息:
call DBMS_STATS.GATHER_INDEX_STATS('username','IDX_T2_X');
更多的统计信息收集参见以下手册dbms_stats包的使用说明:
https://eco.dameng.com/document/dm/zh-cn/pm/dbms_stats-package.html
常用hint,例如改变表的关联顺序,参见dba手册:
https://eco.dameng.com/document/dm/zh-cn/pm/sql-tuning.html#23.6%20%E4%BD%BF%E7%94%A8%E4%BC%98%E5%8C%96%E5%99%A8%E6%8F%90%E7%A4%BA
为什么 测试环境 表扫描用的是CSCN2 + SLCT2 用索引。而生产环境表扫描 用的是SSEK2 + scan_range。