注册
系统视图优化1

系统视图优化1

tdj305 2024/12/16 239 1 0
摘要 最近项目上遇到通过查询all开头的视图性能不满足要求的情况,通过分析改为DM自带视图解决

现场环境
系统移植,上线前压测。
问题现象
压测时CPU使用率超过5000%(8核CPU)。
需求描述
通过系统视图取一张表的列名、字段类型、字段是否可为空、字段默认值以及是否是主键。
处理方法
原始SQL:

select a.column_name, 
       data_type, 
       DECODE (nullable, 
                      'Y', 0, 
                      1) notnull, 
       data_default, 
       DECODE (A .column_name, 
                      b.column_name,1,0) pk 
  from all_tab_columns a,(select column_name 
          from all_constraints c, 
               all_cons_columns col 
         where c.constraint_name = col.constraint_name 
           and c.constraint_type = 'P' 
           and c.table_name = 'T1' and c.OWNER='SYSDBA') b 
 where table_name = 'T1'  and a.OWNER='SYSDBA'
   and a.column_name = b.column_name (+)

注:原始SQL其实有问题,少了and c.OWNER='SYSDBA'条件,这样多个模式下有同样表名的话结果就错了。
原始SQL执行计划:
(计划太长放不下,大家可以直接看这个SQL的计划。)
我们可以看到,原始SQL计划有494行,压测时执行耗时500ms以上,导致CPU使用率无法下降。
优化思路:
因为原始SQL中用到的all_tab_columns、all_constraints和all_cons_columns都是兼容Oracle做的,不是DM自带的视图,思路就是使用达梦自带的系统视图来查询,主要是SYSCONS、SYSINDEXES、SYSCOLUMNS、SYSOBJECTS这几个视图。
但是这里面有个问题,
通过syscons、sysindexes和sysobjects关联可以获取的约束名字,但是获取列名的时候关联syscolumns,这个无法和约束的列名关联起来。
通过all_cons_columns视图查询。

select * from all_cons_columns;

(计划不放,大家自己看)
分析这条SQL的执行计划,可以看到这个视图用到SYSCONS、SYSINDEXES、SYSCOLUMNS、SYSOBJECTS这几个视图,但是关联条件还是无法确定,无法获取某一列是否是索引列。
打开SQL日志,通过manager查看表结构,发现要用到一个函数SF_COL_IS_IDX_KEY(INDS.KEYNUM, INDS.KEYINFO, COLS.COLID)
结果为1才是索引列,如此修改原始SQL就方便了。
修改后SQL:

select o.name table_Name,o3.name owner,cols.name column_name,cols.TYPE$ data_type,DECODE (cols.nullable$,'Y', 0,1) notnull, 
       cols.defval data_default,
       decode(con.type$,'P',SF_COL_IS_IDX_KEY(I.KEYNUM, I.KEYINFO, COLS.COLID),0) PK
from sysobjects o
left join SYSCONS con  on o.id = con.tableid  and con.type$='P'
LEFT JOIN sysobjects o3 on o.schID=o3.ID 
left join SYSINDEXES i on con.indexid = i.id
LEFT JOIN SYSCOLUMNS cols on O.ID=COLS.ID --AND O2.PID=COLS.ID
where o.name = 'T1' AND O3.NAME='SYSDBA';

修改后再压测,发现CPU已下降,问题解决。
经验分享
遇到类似问题,首先要想到的是改兼容性视图为DM自带视图SYSCONS、SYSINDEXES、SYSCOLUMNS、SYSOBJECTS等这几个视图,具体看dba手册,然后根据某个视图查询,再根据执行计划等多方面分析。
关键点:
需要通过一个函数SF_COL_IS_IDX_KEY(INDS.KEYNUM, INDS.KEYINFO, COLS.COLID),结果为1才是索引列。之前把dba视图看烂了也没找到索引和列对应的关系,折腾好久才通过SQL日志定位到。

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服