复杂SQL性能优化的剖析(二)(r11笔记第37天)
公众号:杨建荣的学习笔记 · 作者:杨建荣 · 发布:2017-01-07 23:46:11 · 原文链接
昨天的一篇文章复杂SQL性能优化的剖析(一)(r11笔记第36天) 分析了一个SQL语句导致的性能问题,问题也算暂时告一段落,因为这个语句的执行频率是10分钟左右,所以优化后(大概是2秒左右,需要下周再次确认)的提升很大。
对于优化是一个持续的改进,我们碰到的问题,最终的原因可能五花八门,但是正如柯南所说,真相只有一个。我把这个问题和前几天处理的一个问题结合起来,前几天处理了一个紧急问题,也是有一个SQL语句的执行计划发生改变,这个语句的业务比较关键,触发频率是每分钟一次,如果一旦出现延迟,就是一个连锁反应。目前语句的执行效率其实不大理想,每次平均要25秒左右。对于我来说,这个结果其实是不可接受的。这么说的一个原因是据我所知,在另外一个统计库中,执行同样的语句只需要1秒钟。所以对于这个问题我还是充满信息的。
语句其实也蛮长,但是还得列出来。
select to_char(t2.servertime,'yyyy-mm-dd hh24:mi:ss') as servertime,t2.deviceid,t2.gamechannel, t2.system,t2.device,t2.resolution,t2.dt,t2.appkey from ( select r1.servertime,r1.deviceid,r1.appkey from (select min(servertime) as servertime,deviceid,appkey from sdk_start where dt=:1 group by deviceid,appkey) r1 left join (select deviceid,appkey from h1_active_dev) r2 on(r1.deviceid=r2.deviceid and r1.appkey=r2.appkey) where r2.deviceid is null) t1left join(select servertime,deviceid,gamechannel,system,device,resolution,dt,appkey from sdk_start where dt=:2 ) t2on(t1.appkey=t2.appkey and t1.deviceid=t2.deviceid and t1.servertime=t2.servertime)主要的思路就是在表sdk_start中进行初步的过滤,得到每个设备最早的信息记录,然后和另外一个总表h1_active_dev去匹配(左外连接),得到这些信息之后再来和sdk_start重新关联,得到尽可能详细的信息。两个表的数据量都是千万级。
有了参考的标准,优化也有了一定的方向和章法可依据。
按照目前的执行情况,是对h1_active_dev做了全表扫描,是优化器认为目前最高效的方式。我认真比对了两套环境,数据量相仿,索引信息也是相似的,执行计划却大大不同。
其中的一个不同之处是sdk_start在当前执行效率较差的环境中,尽管是分区区,但是只有一个默认分区pmax,但是我注意到一个情况,同样的环境,另外一个逻辑相似(表名不同)的语句,表也没有分区,执行效率也很高,也是1秒左右。所以目前我只能推断表分区规范后能够提升执行效率,但是具体情况还得测试一下才能论证。
所以目前我更倾向于理解是执行计划的差别,目前的情况如下:

统计库1的执行效率较差,统计库2的执行效率要高。
