热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

一周工作总结--一次SQL优化记录

今天收到一个同事的问题,有一段SQL跑了很久很久,根本没有结果,根据同事的反映,这个SQL一个月比一个月要慢。这是不被允许的事情,我们要做的就是对这个SQL进行一次优化。下面就是这次优化的记

     今天收到一个同事的问题,有一段SQL跑了很久很久,根本没有结果,根据同事的反映,这个SQL一个月比一个月要慢。这是不被允许的事情,我们要做的就是对这个SQL进行一次优化。下面就是这次优化的记录。

     首先说SQL:

select t.month_id,
t1.area_id,
t1.local_id,
count(distinct case
when t.type_id = '02' and t.valid_flag = 1 and
t3.trade_id
= '1008601' then
t.
user_id
else
null
end),
count(distinct case
when t.type_id = '02' and t.valid_flag = 1 and
t3.trade_id
= '1008602' then
t.
user_id
else
null
end)
from product_flag_m t,
... --省略部分都是类似上面的运算,很多,为了节省篇幅都取消了
left join VW_CODE_LOCALNET t1
on t.local_id = t1.root_local_id
LEFT JOIN TRADE_LIST T3
ON T.id2 = T3.id2
AND T3.trade_id IN ('1008601', '1008602')
where t.month_id = '201212'
group by t.month_id, t1.area_id, t1.local_id;

      这段代码隐藏了敏感信息,可能会有一些修改的时候错漏的问题。

      接下来就是比较老的套路了,查看这段SQL的执行计划:

      

      这个时候可以初步判断是因为product_flag_m表太大造成的查询效率低下。既然只需要12月的数据,那么我自然而然的想到了将12月的分区压缩一下,利用压缩表的特点进行查询效率的提高。但是这是张生产表,不能随便操作,于是我就将12月份的type_id='02'的数据单独抽取出来形成一张新的表,当然这张表是压缩过的,而且我抽取的时候只抽取自己需要的字段,这样做的好处是尽量减少数据量,减轻数据库的负担。

     下面就是使用了压缩表之后的执行计划:

     

       可以看到COST是有所降低,但是这个和没有降低没什么区别。还是面临执行不出来的问题。

       这个时候我注意到了ID=2的这一部执行计划。在id=3的hash join right outer之后,不管是COST还是BYTES都是在一个比较正常的水平之内的,那么问题就应该出在TRADE_LIST这个表上。

       这个表是一张编码表,本身并不大,但是注意这里:

       

       上图所示应该就是罪魁了。于是我想到了,既然最后需要过滤一下trade_id,那么为什么不直接就用一张只有trade_id为1008601和1008602的表呢?

       于是我鬼使神差的建立了一张视图,这个视图就是只取了上面说的那么多数据,然后替换掉原来的SQL中的TRADE_LIST,删除了其中的

AND T3.trade_id IN ('1008601', '1008602') 语句,再看执行计划:

       

        这个效果就非常好了。

        我本身很担心这个视图用了以后会影响查询结果集。于是我自己造了一张表做了一个小测试。test3中有object_id为2, 3, 4, 5, 6, 7的记录,编码表中只有id为2, 3, 4, 5, 6的编码记录,SQL如下:

        

select t1.object_id, t2.id, t2.name
from test3 t1
left join test4 t2
on t1.object_id = t2.id
and t2.id in (2, 3);

       这个结果有48行。制造一个视图:

create view test5 as select * from test4 where id in (2, 3)

      然后替换成视图:

      

select t1.object_id, t2.id, t2.name
from test3 t1
left join test5 t2
on t1.object_id = t2.id;

      结果还是48行。也就是说这个方法是可行的。

      这样的话,如果在原来的SQL上加上并行提示,效果会更好。经过我的实际测试,3分钟以内就跑出了所有的结果。

      或许会有人问我,为什么不加上索引?我并不是反对加索引,我不习惯使用索引的习惯是因为我们的现实环境所限,我们的磁盘空间基本上每隔一段时间就会满,所以我没办法随心所欲的添加会占用空间的索引,而是更倾向于使用压缩表,节省表空间。而且,id2字段进行关联的时候有一个隐式类型转换,这个字段起码没有办法加索引。至于其他字段,我没办法实验,如果有机会,可以做个实验试试。

       


推荐阅读
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • 使用nodejs爬取b站番剧数据,计算最佳追番推荐
    本文介绍了如何使用nodejs爬取b站番剧数据,并通过计算得出最佳追番推荐。通过调用相关接口获取番剧数据和评分数据,以及使用相应的算法进行计算。该方法可以帮助用户找到适合自己的番剧进行观看。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • 本文介绍了在Vue项目中如何结合Element UI解决连续上传多张图片及图片编辑的问题。作者强调了在编码前要明确需求和所需要的结果,并详细描述了自己的代码实现过程。 ... [详细]
  • Oracle seg,V$TEMPSEG_USAGE与Oracle排序的关系及使用方法
    本文介绍了Oracle seg,V$TEMPSEG_USAGE与Oracle排序之间的关系,V$TEMPSEG_USAGE是V_$SORT_USAGE的同义词,通过查询dba_objects和dba_synonyms视图可以了解到它们的详细信息。同时,还探讨了V$TEMPSEG_USAGE的使用方法。 ... [详细]
  • 本文讨论了如何使用IF函数从基于有限输入列表的有限输出列表中获取输出,并提出了是否有更快/更有效的执行代码的方法。作者希望了解是否有办法缩短代码,并从自我开发的角度来看是否有更好的方法。提供的代码可以按原样工作,但作者想知道是否有更好的方法来执行这样的任务。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • Redis底层数据结构之压缩列表的介绍及实现原理
    本文介绍了Redis底层数据结构之压缩列表的概念、实现原理以及使用场景。压缩列表是Redis为了节约内存而开发的一种顺序数据结构,由特殊编码的连续内存块组成。文章详细解释了压缩列表的构成和各个属性的含义,以及如何通过指针来计算表尾节点的地址。压缩列表适用于列表键和哈希键中只包含少量小整数值和短字符串的情况。通过使用压缩列表,可以有效减少内存占用,提升Redis的性能。 ... [详细]
  • 本文介绍了在处理不规则数据时如何使用Python自动提取文本中的时间日期,包括使用dateutil.parser模块统一日期字符串格式和使用datefinder模块提取日期。同时,还介绍了一段使用正则表达式的代码,可以支持中文日期和一些特殊的时间识别,例如'2012年12月12日'、'3小时前'、'在2012/12/13哈哈'等。 ... [详细]
  • 在Oracle11g以前版本中的的DataGuard物理备用数据库,可以以只读的方式打开数据库,但此时MediaRecovery利用日志进行数据同步的过 ... [详细]
  • 本文介绍了Oracle存储过程的基本语法和写法示例,同时还介绍了已命名的系统异常的产生原因。 ... [详细]
  • 本文介绍了响应式页面的概念和实现方式,包括针对不同终端制作特定页面和制作一个页面适应不同终端的显示。分析了两种实现方式的优缺点,提出了选择方案的建议。同时,对于响应式页面的需求和背景进行了讨论,解释了为什么需要响应式页面。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 在很多数据库中都存在一个自动增长的列,如果现在要想在oracle中完成自动增长的功能,则只能依靠序列完成,所有的自动增长操作,需要用户手工完成处理。语法:CREAT ... [详细]
  • 本文介绍了一个误删Oracle数据文件导致数据库无法打开的问题,并提供了解决方式。解决方式包括切换到mount状态、离线删除报错的数据文件等。 ... [详细]
author-avatar
CCTV2财经2677
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有