1.问题表现:
前端WEB页面,某个结算中心,结算过程卡死,长时间无响应。
2.慢sql定位
查看卡住的存储过程为:
PKGI_Settle.up_ParallelSettleOutputEx(?,?,?...);
定位具体慢sql为某张临时表的关联查询。
3.分析处理
1)事务级临时表,事务结束,临时表数据为空,临时表的执行计划依赖数据库动态生成,难以在存储过程之外查看具体的执行计划。存储过程有近万行,不好排查定位。
2)于是将临时表改建为普通表,执行过程装入数据,收集统计信息后,再来排查。此时发现,在关联查询阶段并不慢。问题转移至下一张临时表的关联查询上。
这里考虑Oracle的临时表和统计信息,在Oracle中收集临时表的统计信息,反而可能造成错误的执行计划。尤其不能收集事务临时表的统计信息,否则错误收集空表信息,误导执行计划的代价估算,容易造成严重的性能问题。
DM8 应该也是出现了类似情况,怀疑在收集全库的统计信息阶段,错误地连同临时表一起收集了,应该删除临时表的统计信息,由数据库去动态采样。
按照这个思路,在达梦中做以下处理:
3)查看统计信息收集情况
查询相关动态视图(如:SYSSTATS),果然发现有很多临时表存在统计信息
4)删除临时表统计信息
--查询临时表
select * from ALL_OBJECTS where "TEMPORARY"='Y' AND owner='SETTLE' AND OBJECT_TYPE='TABLE';
查出来有900多张临时表。
--生成批量删除统计信息的sql
select 'dbms_stats.delete_table_stats(''SETTLE'','''||object_name||''');' from ALL_OBJECTS where "TEMPORARY"='Y' AND owner='SETTLE' AND OBJECT_TYPE='TABLE';
执行批量删除sql
5)验证性能问题得到解决。