一次巧妙的SQL优化改写技术人生系列

不知不觉技术人生系列已经来到了第四十期,前面我们分享了各种精彩案例,在与众多读者的交流中发现许多读者有对SQL优化的案例的需求,通常我们认为,SQL优化涉及的信息会比较多,比如需要各种表的数据分布信息,索引信息,统计信息等,有时还跟业务逻辑紧密相关,所以SQL优化的案例在我们技术人生系列的分享中出现的次数较少;不过今天,我们要分享的SQL优化案例能充分体现SQL优化的技巧,忍不住要将精彩奉献给大家…

如果您看到下面的执行计划:

而其单次执行的逻辑读达到1.6亿个,执行时间将近秒的情况下:

你会如何优化呢?单从执行计划你能想到的优化方案在哪里呢?

今天我们就来看看我们的海猫是如何巧妙的优化这一语句,如何一步步将原本执行时间需要秒的SQL优化到1秒!!

不过开始我还是插播一条广告(不喜勿喷,不想看广告的可以直接跳到案例章节):

案例分享前的小广告

技术人生系列(每周四首发)已经出到了四十期,期间,很多读者咨询关于Oracle数据库实战培训的事情,于是,我们开始了第一期培训,帮助大家极致地使用数据库,而不是浅尝辄止,同时提升大家的职业价值(money)…

问题来了!!

大清早的,睡眼惺忪的,正在美梦中,电话响了,问题来了……

客户简明扼要的描述了一套业务系统,正在执行跑批,现在负载一直在飙高,而且居高不下,希望我们予以解决。目前已经提前收集了一些awr等相关信息。并发来当时的zabbix的负载图,有点吓人,一片蓝蓝的,负载全满了:

这的确让客户有点捉急……

随后客户还提供了他隔一分钟查看的session会话情况:

间隔一分钟:

简单确认问题

看了客户提供的几张session的截图,我了然于心,完全淡定了。从现象看这是典型的CBC(cachebufferschains)问题,也可以说是热点块的问题。而且客户已经找到导致问题的SQLID,那么很简单,这个SQL就是罪魁祸首。

根据以往的经验,这种情况,基本上SQL优化掉,问题就迎刃而解了。但是为了保险起见,我还是持续观察了下v$session的情况,观察了一段等待事件latch:cachebufferschains的p1,p2,p3的情况,确认SQL并没有hang住,只是跑的比较慢,一直在扫描某个对象的数据块。

这种情况,一般就不用纠结了,很快定位是SQL语句性能的问题,而且需要更进一步分析SQL执行的情况。

开始分析问题

从目前诊断来看,问题已经很明朗。就是sql语句导致的性能问题,从而表现出来资源消耗很高、业务反应很慢的情况。那么,既然问题已经确定了,作为DBA的你下一步会怎么做呢?

基本上两种情况:

(1)作为DBA我已经把问题诊断的差不多,就是业务sql性能导致的问题,可以丢给业务部门,让开发一个劲去优化就好了;所以感觉接下来似乎就是开发的事情,跟我们DBA没有一点关系,soeasy有木有!!

(2)就是DBA本身就有能力去把问题SQL搞定,提供强有效的优化方案,让SQL执行的飞快,最终在我们DBA这一关,就把问题全部搞定。如果是您,会怎么选择呢?

其实个人还是觉得优化SQL应该还是我们自己的事情,丢给开发,一来显得我们自身太弱,二来或许也会阻挡我们更深入的认识oracle,技术上会一直有缺口。再说,一个相当经典的优化案例,既可以训练自己的优化,又可以帮帮客户,当然如果可以的话,也可以装装逼,呵呵。。。一举N得,何乐而不为?

OK,那么可以开始优化SQL了。

0

1

从最基本的开始,首先要大概看懂SQL语句简简单单表达出来的意思,无论是逻辑上或者业务上,我们总要做到心里有数,当前的这个SQL语句:

从SQLtext上来看,本身并不是长达数百行的SQL语句,看起来不会把我们唬到;至少从心理上,我们不会害怕去面对它了。对于SQL语句,我们都习惯了看三个部分。

第一.Select部分:这里是很简单,就是count(*),期望得到一个总数。一般这种的count或者sum之类聚合函数作为最后的结果,心里大概有个预设,就是涉及的表的行数应该都是比较多的。不然求个总数或总和似乎意义不大;

第二.From部分:很明显的三表关联,做内连接。这个没有什么特殊的地方;

第三.Where部分:这里where条件部分稍微复杂一点点,总体是or连接起来的两个过滤条件。看样子都是对T表的过滤。

但是对T.END_的过滤部分有一个子查询:

知识普及

在这里我们要特别留意这个子查询,这点对我们的优化很重要。而对于各种子查询特性的掌握,恰恰对于我们SQL优化有很大的帮助。据了解,其实很多DBA还是不太熟悉一些常见的子查询。我们知道一个子查询就是一个嵌入SELECT语句中的另一个SQL语句的子句,而它的位置很灵活。我们常见的,比如select部分有子查询:

我们称之为标量子查询。这种子查询在真正的业务SQL中是非常非常常见的;标量子查询有个最大的特点,叫做“单行单列”;就是说:这个子查询的结果集,一定是唯一一个值,不会同时出现多个值,而且标量子查询还是比较容易出现性能问题的,是我们优化常常需要







































北京白癜风哪家比较好
北京青少年知名白癜风医院



转载请注明:http://www.xcqg58.com/jbjj/jbjj/7679.html