暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

多种优化方案感受殊途同归

godba 2020-11-11
438

背景:

早上同事说,查询有一个页面出不来结果,登陆db上看正在执行的sql,看到有5sql长的都差不多,已经执行了100s左右。同事说这个功能很重要,迫切需要优化。

基本情况:

SQL:稍微做简化处理

SELECTt.PROC_RESULT_ID     as"ProcResultID", .... t.CreateName         as "CreateName"FROM (SELECTROWNUM  AS rowno, .....t6.FIRST_NAME         AS CreateName

 FROM PC_PR_HEADER      t1,  USR_RL_DM_MAP_ORG t2,

 USR_RL_DM_MAP_XY  URDM_ORG,   USER_ROLE_MAP     URI,

 USER_PROFILE      t5,  CONTACT           t6

 WHERE (t2.ORG_ID = t1.OWNER_ORG_ID AND (URDM_ORG.ENTITY_ID =t2.ROOT_ORG_ID AND

  (URI.ROLE_ID = URDM_ORG.URM_IDAND (URI.USER_ID ='USERORG000010001'))))

   AND t5.ID = t1.CREATED_BY    AND t6.ID = t5.CONTACT_ID

 AND URDM_ORG.DOMAIN_TYPE_ID = 'CUST'   AND ROWNUM <= 50.0

  and t6.FIRST_NAME = '管理员二'

 and t1.CREATED_DATE >=  TO_DATE('06/01/2017 00:00:00 ', 'mm/dd/yyyyhh24:mi:ss')

 and t1.CREATED_DATE <= TO_DATE('06/03/201723:59:59 ', 'mm/dd/yyyy hh24:mi:ss')

         ORDER BY t1.CREATED_DATE DESC) t

 WHERE t.rowno > 0

从等待事件分析

几个会话的等待事件均为:latch cachebuffer chains 根据等待事件的p1raw找出具体对象:C000000552D2CD58是从等待事件中查询得出这里不多说了......

selecta.hladdr, a.file#, a.dbablk, a.tch, a.obj, b.object_name  from x$bh a, dba_objects b

 where (a.obj = b.object_id or a.obj =b.data_object_id) 

anda.hladdr in ('C000000552D2CD58')

union

selecthladdr, file#, dbablk, tch, obj, null from x$bh

 where obj in (select obj  from x$bh where hladdr in ('C000000552D2CD58')

               Minus    select object_id    from dba_objects

               Minus  select data_object_id from dba_objects)

   and hladdr in ('C000000552D2CD58')

 order by 4;

pc_pr_headert1file74,数据块是3409135. tch116,已经很高。再进一步确认热点块:

 select * from (select CREATED_DATE,dbms_rowid.rowid_block_number(rowid)as blockid,

  dbms_rowid.rowid_relative_fno(rowid) as fileid

  from PC_PR_HEADER t1)  where fileid = 74 and blockid = 3409135

执行计划:


确认到热点块在T1表中,根据SQL中的条件 进一步确认

WHERE  t2.ORG_ID = t1.OWNER_ORG_ID ....

   AND t5.ID = t1.CREATED_BY   ....

 and t1.CREATED_DATE >=  TO_DATE('06/01/2017 00:00:00 ', 'mm/dd/yyyyhh24:mi:ss')

 and t1.CREATED_DATE <= TO_DATE('06/03/201723:59:59 ', 'mm/dd/yyyy hh24:mi:ss')

结合执行计划中的是nested_loop 的被驱动表,父节点是ID = 7. 因此建立组合索引。 考虑到等值关联,和where条件使用频率和选择性。 建立索引

create index ind_pph_candel on  PC_PR_HEADER(OWNER_ORG_ID,CREATED_BY,CREATED_DATE)  online;

从SQl以及数据量上面分析

其中ID=7 NESTED LOOPS id=8是驱动表,id=24是回表再过滤。

查询Id= 8有多少条数据 

select count(*)

   from USR_RL_DM_MAP_ORG t2, USR_RL_DM_MAP_XY URDM_ORG,USER_ROLE_MAP URI where URDM_ORG.ENTITY_ID = t2.ROOT_ORG_ID

    AND URI.ROLE_ID = URDM_ORG.URM_ID

    AND (URI.USER_ID = 'USERORG000010001')

and URDM_ORG.DOMAIN_TYPE_ID = 'CUST';

大概有1.3W;这和cbo算出来的1条是不同的

 那就说明id=25要被扫描1.3w次了,而且每次都要回表再过滤,要回表1.3w次。而x$bhtch116的对象是表,而不是索引,那应该就是回表导致的热块了。


所以创建的组合索引,其原理把需要的数据放入索引中,之后直接在索引中过滤数据即可,而不是像现在再次回表后过滤。从而减少逻辑读。另外这边如果ID = 7 这边如果改成hash 关联,是否也能减少执行成本呢?(读者可以思考下)。

效果对比:

很明显执行成本减少很多, 原先100S+,也到秒杀了。

总结:

该案例从两个不同的角度出发,定位到同一个性能瓶颈,这要对系统级知识点有深度的考验。人说:旅途重要的不是目的地,而是沿途的风景。

同样分析问题结果重要,其过程更重要,因为在环环相扣的细节,分析其原因,探索其本质。然后有所收,有所获。





文章转载自godba,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论