• 左连接造成的一些问题


    左连接造成的一些问题

    今天有同事告诉我,有个SQL执行了好久好久执行不出来,我说好就是多久?她说一天左右了。真是令人咋舌的SQL。于是我要来了SQL看了看执行计划,确实让人咋舌。

         下图中就是执行计划的截图:

         

         25G的COST和75T的Bytes确实是无法承受之重。这个SQL是这样子的:

          

          select部分做了很多sum运算,还有distinct等运算,总之很麻烦,group by部分就是上面的维度。其中最大的表是TABLE3和TABLE4,这两个表所需要查询的数据量都在3G以上,各自差不多3000万数据。

          最开始我以为是因为数据量大的原因导致的这个执行计划不可实现,但是在我将TABLE3和TABLE4的相应数据进行压缩后,数据量尽管各自降低到了1G左右,但是执行计划基本上没有改变,这不是我要的效果,于是我注意到了执行计划中红色框中的部分。是不是这里导致了问题的发生?于是我开始检视SQL,就发现了一个问题:TABLE4实际上只有201302的数据,但是为什么这里还需要在左连接的时候写上月份标识,这个比较不合理,而且根据我以往的经验判断,左连接或者右连接的时候,如果and条件写的太多,往往会影响执行计划,导致SQL长久的无法得到结果。于是我做了一个很简单的事情,就是把TABLE4的month_id部分去掉,后来我又进了一步,将TABLE3的month部分也去掉了,这是一个分区表,于是我用了这个办法:

         left join TABLE3 partition(part_02),这样即实现了减少and条件的目的,又不会影响数据准确的效果,一举两得。在进行了相关的优化之后,执行计划变成了这个样子:

        

         可以看到执行计划发生了翻天覆地的变化,直接能看到的就是少了NESTED LOOPS OUTER,取而代之的是图中1部分和2部分的HASH JOIN OUTER和TABLE1的HASH JOIN OUTER,这是我喜欢看到的事情,我就喜欢看到简单的执行计划。虽然这个COST依旧很大,但是我实在不想动弹了,这个的数据量实在是太巨大了,我面对的优化工作难度已经无法让我有精力想过去那样,仔细研究思考,然后把COST弄到几千或者更小的程度了,就这样吧,天要下雨,娘要嫁人,随他去吧。

         我以前看到论坛上或者书上都在写,如果你的表超过1G,那么最好进行分区,这句话现在我深有体会,如果没有分区表,这个SQL也没有办法优化了(或者说我就没有能力去优化了),因为没有办法去掉month的条件,除非是将特定月份的数据取出来建立一个中间表,不过那么做似乎有点麻烦了,不符合我一贯喜欢写短代码的习惯。

     
     
    分类: Oracle管理
     
  • 相关阅读:
    Java数据结构和算法总结-数组、二分查找
    Android开发必知--使用View.setId的正确姿势
    Fiddler基本用法以及如何对手机抓包
    Android学习笔记(十四)方便实用的首选项-PreferenceActivity
    Android学习笔记(十三)SharedPreference必须掌握的基础
    设计模式之单例模式
    关于如何控制一个页面的Ajax读数据只读一次的简单解决办法!
    ASP.NET MVC 表单提交多层子级实体集合数据到控制器中
    使用Bootstrap的popover标签中嵌入插件,并且为插件注册事件实现Ajax与后台交互
    关于.Net使用企业库访问MySql数据库
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2987652.html
Copyright © 2020-2023  润新知