编辑手记:Oracle线上嘉年华,正在持续分享中。本次的主题是系统割接中的SQL解析问题和结合业务的SQL优化改写技巧。

1嘉宾介绍


小鱼(邓秋爽)

云和恩墨专家,有超过5年超大型数据库专业服务经验,擅长oracle 数据库优化、SQL优化和troubleshooting

新系统割接的library cache问题

这是我们在做系统割接的时候的一个案例,可能并不是很常见,这个案例是将Oracle 11g升级到12c的时候遇到的问题,出现了大量的library cache的问题。具体情况是:

新系统割接后,不定时出现大量library cache lock、library cache:mutex X,几分钟后系统自动恢复。

在短暂的时间里,我们来不及做systemdump的,而且出现的频率和时间也是不固定的,很难抓取到当时系统的信息。

先获取故障时段的AWR报告:

我们看到这两个等待事件已经占了整体DB time的72%,大家看到这个问题,可能一般都会想到解析,

我们从以下几个角度分析:

  • TopSQL的解析、执行频率是否合理:

故障点的library lock相关的SQL来看,基本占据db time、parse阈值高的Top SQL解析、执行频率并没有数量级的增加,他们更像是受害者。

  • Oraclebug是否存在:

系统版本Oracle 12.1.0.2,经过原厂排查并不存在相关bug引起。

  • SQL解析是否存在问题,绑定变量使用分析:

查看awr报告硬解析次数很高,但是挖掘sharedpool发现系统中并未发现大幅度未使用绑定变量的SQL。

在oracle 10g的时候,V$SQLAREA视图有一个FORCE_MATCHING_SIGNATURE 参数,可以将SQL经过绑定变量代替后生成一个hashvalue值,通过这个值找到未使用绑定变量的SQL,而开发商的SQL的质量比较高,并未发现核心业务SQL未使用绑定变量的情况。

这样看来,这个问题是很棘手的,硬解析次数很高,但我们找不到对应的SQL在哪里。

我们接着分析,来看AWR报告里面的time model statistic

我们看到红色标记的部分,解析时间消耗了63.74%、解析失败消耗了50.55%。

解析失败是什么?Oracle的解释是这样的:

failed parse:语法、权限等无法执行的SQL解析,也是硬解析,并且解析失败是不能被重用的,当然它也不会存储在V$SQLAREA视图中,所以也挖掘不到这类SQL。

我们如何去发现在系统中解析失败的SQL呢?

Oracle提供了event 10035,会将解析失败的SQL记录到alert 日志里面

从上面的日志可以看到各种解析错误的代码,其中error=942,表示:表不存在,因此判断这是他们做系统变更的时候做过一些表的删除,我们可能在系统割接的时候都会做一些旧表的drop或者rename,这时候一定要严格挖掘应用端的代码,将下线的业务代码停掉,避免错误解析导致数据库出现严重的性能问题。

SQL优化改写技巧

接下来和大家分享执行计划结合业务逻辑的一个等价改写的例子

案例中的SQL如上,大致由两部分组成,上下各是一个标量子查询,然后用union all联合在一起做了一个order by,在结果显示中使用了分页。

我们通过脚本获得该SQL单次逻辑读将近18000000.返回行数为10行,响应时间达到104036MS。

这是个很复杂的SQL,包含标量子查询、表连接、unionall、排序、分页,还有一些复杂的decode、nvl等函数,通过awr报告我们得知该SQL单次执行需要1500多万到1900多万的逻辑读,平均都只返回10行数据,单次执行时间也要100秒左右。

我们可以将SQL简化如下:

select * from (select row_.*, rownum

rownum_ from

(SELECT ST.* FROM (Select …TO_CHAR(T.SIGNDATE,

‘YYYYMMDDHH24:MI:SS’) AS SIGNDATE …(标量子查

询1)、(标量子查询2)... From

MM_MK_CUSTMGR_SIGN T WHERE T.REGION = 14

Union all

Select …TO_CHAR(T.SIGNDATE,

'YYYYMMDDHH24:MI:SS') AS SIGNDATE …(标量子查询

1)、(标量子查询2)... From MM_MK_CUSTMGR_SIGN T

WHERE T.REGION = 14

AND T.SIGNOUTOID IS NOT NULL) ST

ORDER BY SIGNDATE DESC) row_ where rownum <= :1)

where rownum_ > :2

 

对于这种复杂的SQL,我们先看执行计划

这个执行计划我们做过相应删减。

在优化SQL中,我们优先考虑能否优化cost高的步骤,比如大表全表扫描、大表全索引快速扫描、跳跃索引扫描、大表排序等cost消耗;

其次看filter(优化了的nestedloop)、nested loop、hash join、笛卡尔积等表关联步骤cost消耗。

在上面的标量子查询中,Cost消耗最高的在这个view操作,COST消耗达到了14M、rows达到了501K,而这个view是由两部分union all组成的。

在下面的标量子查询中,两部分union all发现上层部分主查询MM_MK_CUSTMGR_SIGN T估算返回501k Rows,下层主查询则只有1Rows数据。

注:在Oracle的估算中是不存在0 Rows的情况,如果评估的结果是0,会算作1.

对于标量子查询,我们简单做个介绍,就是说优化器在这种情况下永远只做一种操作就是filter,这是一种变相优化nest loop。对于这种标量自从查询,我们知道其实SQL之所以出现问题是因为下面的501k导致需要驱动上面那堆复杂的标量子查询,

那么如何优化呢?

常规优化:对于标量子查询,可以使用等价改写为表的外连接方式让其走hash jion的执行计划,但是如果标量子查询中有大表则并不合适,该SQL恰恰包含大表,并不适合用常规的等价外连接的方式来改写。

业务结合执行计划分析:那么这个ORDER BYSIGNDATE DESC排序后rownum能否推进到主查询MM_MK_CUSTMGR_SIGN T表中,rownum限制后再去驱动标量子查询,减少标量子查询的循环次数。

接下来主要针对第二种,结合业务进行分析改写。

在上面的SQL中,是先取501k数据做了驱动,然后再做标量子查询和order by的操作,我们能不能把order by的操作推回到标量子查询前面,这样子的话标量子查询要驱动的只是前面排序取rownum限制条件的数据,我们通过画图的方式来分析一下:

首先是两个同样的表,做了标量子查询的操作,这里的数据是501k,然后标量子查询完了之后,做了order by后rownum的限制,这是原SQL的执行业务逻辑。

我认为应该写成这样,我们想限制标量子查询的循环次数,那我们就先去对主查询取order by排序rownum限制后的数据,再将主查询取出来的这部分数据去驱动标量子查询,做完后再做一次order by rownum的限制。(这里并不会改变SQL的业务逻辑,虽然我们是先排序取rownum限制了,但是标量子查询时主查询是先排序还是后排序取rownum限制对于主查询返回结果集没有任何影响)

根据这种思路,我把SQL改写如下:

SELECT * FROM

(SELECT row_.*, rownum rownum_ FROM

(SELECT ST.* FROM

(SELECT …TO_CHAR(T.SIGNDATE,

‘YYYYMMDDHH24:MI:SS’) AS SIGNDATE …(标量子查询1)、(标

量子查询2)... FROM

(SELECT * FROM tbcs.MM_MK_CUSTMGR_SIGN x

WHERE x.REGION = 14

ORDER BY SIGNDATE DESC offset :2 rows

FETCH NEXT :1 rows only) T

UNION ALL

SELECT …TO_CHAR(T.SIGNDATE,

'YYYYMMDDHH24:MI:SS') AS SIGNDATE …(标量子查询1)、(标

量子查询2)... FROM

(SELECT * FROM tbcs.MM_MK_CUSTMGR_SIGN x

WHERE x.REGION = 14

ORDER BY SIGNDATE DESC offset :2 rows

FETCH NEXT :1 rows only ) T

) ST ORDER BY SIGNDATE DESC) row_

WHERE rownum <= :1)

WHERE rownum_ > :2

其中红色部分是12C的改写方式。是用一个分析函数的方式去做的。

它的执行计划如下:

先访问表MM_MK_CUSTMGR_SIGN排序取rownum限制(前10行数据后),再去驱动那堆复杂的标量子查询,最后再次排序取rownum条件数据,逻辑读从千万级降低到了26661。

这个SQL在改写后,资源消耗降低了许多,基本上能够满足业务的需求。

如果我们再去剖析原SQL代码,发现union all部分是同一个MM_MK_CUSTMGR_SIGN表的查询,下面那个UNION ALL部分查询出来的结果是上面UNION ALL部分的子集。

而跟研发沟通发现实际上union all的下层查询可以去掉,去掉后则该SQL无需改写rownum就可以直接推进到主查询中,从这个例子可以看到不严谨的代码容易造成性能隐患,影响优化器评估最合理的执行计划。

通过以上分享,我们得出:

1、线上系统变更、表下线需要严格挖掘应用端代码,避免因为表结构变更导致SQL解析错误。

2、复杂业务逻辑对应的SQL需要核查,对于不需要的结果和表关联等尽可能去掉,简化表关联数量,合理利用优化器。

 


文章转自数据和云公众号,原文链接

【云和恩墨大讲堂】Oracle线上嘉年华第二讲相关推荐

  1. 重磅回归丨2020云和恩墨大讲堂,线上线下同步开讲!

    我们回来啦! 去年,「云和恩墨大讲堂」启动了定期的线上分享,邀请数据库行业专家进行线上直播,议题涵盖原理解析.应用实践.心得体会--获得了热烈的反响.今年,我们将大讲堂全新升级,增加了线上+线下联动的 ...

  2. 线上活动丨Kubernetes Operator 开发范式 - 云和恩墨大讲堂201912

    本期主题:Kubernetes Operator 开发范式 - 云和恩墨大讲堂201912 分享时间:2019年06月04日 20:30 - 2019年06月04日 21:30   线上活动 吴叶磊 ...

  3. 线上分享|云和恩墨大讲堂201902:MySQL基础之体系结构

    云和恩墨大讲堂又和大家见面了! 2018年云和恩墨大讲堂走过了祖国的大好河山,从大连到海口,从上海到昆明--不知道我们的课堂里有没有出现过你的身影. 2019我们也不会停下分享的脚步.不过这一次,我们 ...

  4. 线上分享丨自治时代DBA的技能库:SQL和PL/SQL的深度编程(附上期PPT和视频)-云和恩墨大讲堂201905...

    云和恩墨大讲堂又和大家见面了! 2018年云和恩墨大讲堂走过了祖国的大好河山,从大连到海口,从上海到昆明--不知道我们的课堂里有没有出现过你的身影. 2019我们也不会停下分享的脚步.不过这一次,我们 ...

  5. 【云和恩墨大讲堂】戴明明 - 基于 PCIE 闪存卡的 Oracle 数据库使用

    "云和恩墨大讲堂" 线上课程周四晚分享继续.本次我们邀请到的嘉宾是宝存科技的技术专家 - 戴明明(Dave),同时也是一位 Oracle ACE Association. 他将给大 ...

  6. 【云和恩墨大讲堂】高凯 | Oracle 12c 新特性-多租户的维护管理

    "云和恩墨大讲堂" 线上课程周四晚继续开讲.本期我们邀请的嘉宾是云和恩墨西北区技术专家 - 高凯,在这里跟大家分享一下 Oracle 12c 新特性方面的主题.课程以图文形式在微信 ...

  7. 云和恩墨大讲堂新春第一讲-Oracle安全特性之加密登陆

    "云和恩墨大讲堂" 新春第一讲开讲啦!本期我们邀请的嘉宾是太极计算机股份有限公司数据库专家赵全文.课程以图文形式在微信课堂群全程同步直播,请准时守候. 1 课程介绍 名称:云和恩墨 ...

  8. 【云和恩墨大讲堂】盖国强 - Oracle 数据库的架构演进和我的学习之路

    "云和恩墨大讲堂" 线上课程周四晚分享继续.本期我们的分享嘉宾是中国地区首位 Oracle ACE 总监,同时也是云和恩墨创始人 - 盖国强先生.他将围绕两方面主题展开,Oracl ...

  9. 【云和恩墨大讲堂·七月新篇章】Oracle 12c Remote Filewatcher的实施

    光阴如白驹过隙,转眼间2017已经走过了一半.我们一路上收获经验也收获成长,云和恩墨伴你筑梦未来!七月,我们依旧分享不停歇!相约本周四20:30(7月6日),不见不散. 本期主题 Oracle 12c ...

最新文章

  1. Jupyter notebook与Spyder集成
  2. origin+matlab基础绘图
  3. Atitit.注册跟个登录功能的实现attilax总结obo
  4. 【Tools】WireShark3.2安装教程详解
  5. 使用.Net 1.1的项目,TreeView控件不能正常显示
  6. css3制作滚动按钮
  7. shiro扩展获得用户登录类型并提供cookie的方式记住用户密码
  8. 简约好看导航栏(HTML、CSS)
  9. 改变图片局部透明度,实现透明度根据位置不而渐变
  10. 计算机网络技术基础(作业2)
  11. linux开发arm音量加减代码,arm-linux学习:最简驱动模块(示例代码)
  12. python中arcsec_python – 更好的方法来计算Skyfield中两个物体的明显角度分离?
  13. Android视频编码的坑
  14. Exchange反垃圾防病毒网关——SecurityGateway基本部署
  15. Hive微博数据统计分析
  16. 计算机主板检测卡0d,主板检测卡的0d码是什么意思?
  17. centos linux7 开启桌面命令,centos7如何在桌面打开终端
  18. 【Tools系列】之Excel冻结窗格
  19. Android+刷固件,(57M2)海信ip906h强刷系统安卓固件包及刷机教材
  20. RHCE怎么报名?需要什么条件?

热门文章

  1. php设计模式 - 建造者模式
  2. [WebService]之代码优先方法与契约优先方法
  3. WPF and Silverlight 学习笔记(十):WPF控件模型
  4. Nginx + Tomcat 负载均衡集群配置
  5. java输出机票问题_java编程,机票例题纠正改错,谢谢
  6. 编程难学?3点解答你的疑惑
  7. Python可迭代的对象与迭代器
  8. CentOS 6 EOL后如何更换yum源?
  9. mysql 带宽字段_技术分享 | 网络带宽如何影响 MySQL 性能
  10. 如何用matlab读取npz文件,Python Numpy中数据的常用的保存与读取方法