Oracle日期函数SQL改写优化

Oracle idb 801℃ 0评论

日期: 2018-06-16

操作系统

数据库版本

定位问题SQL

从Linux的TOP命令中,看到有一个Oracle进程长期占用20%的CPU使用率,根据操作系统的进程ID,查找v$session中对应的SID,然后通过ASH报告(执行脚本是:@?/rdbms/admin/ashrpti.sql,时间范围是1个小时,这个看需求而定),找到该SID在1小时内执行的SQL语句,其中有一条语句如下,跟人觉得有问题。

问题SQL:

在和研发同事沟通之后。了解到该语句是统计一天的对应条件的数据量。而且是定期地执行。

查看表结构

查看表是否有索引

从这里可以看到where 条件trunc(TASK_DATE)中的TASK_DATE是有B-TREE索引,也就是常用的默认索引。但是因为没有建立对应的函数索引,因此猜测这个语句并没有走索引。

查看表的总记录数

源SQL的执行计划

从下面的SQL执行结果可以看到,结果集占全表的数量记录数比例很小,此处应该是走索引才是更加高效的。

SQL改写

换一种思路来实现这个统计一天的数据量,即比较时间从当天的00:00:00至当天23:59:59。从下面可以看到SQL改写之后,走了TASK_DATE列创建的索引。从Cost(代价)及Time(执行时间)都可以看出明显少于前面的全表扫描。

合并查询查看执行计划

因为TASK_VALID条件之有2个值,即Y或者N(可以考虑创建位图索引,这里先不讨论),而且还是动态变化,为了比较保证改写后的查询结果一致(SQL改写的前提就是实现的逻辑结果必须一样),进行下面的合并查询,然后查看执行计划。

总结

上面的例子,其实是很常见的索引失效场景,即在普通索引的列加上了函数,导致原先的普通索引失效,从而走了全表扫描。

##上面的过程改写测试过程及结果和实际的业务场景有关系,加上个人经验有限,可能存在表述不准确之处,还请批评指正。

转载请注明:猫头鹰工作室 » Oracle日期函数SQL改写优化

喜欢 (0)or分享 (0)
Avatar
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址