Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1344904
  • 博文数量: 169
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 3800
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-30 13:00
个人简介

About me:Oracle ACE pro,optimistic,passionate and harmonious. Focus on ORACLE,MySQL and other database programming,peformance tuning,db design, j2ee,Linux/AIX,Architecture tech,etc

文章分类

全部博文(169)

文章存档

2024年(24)

2023年(28)

2022年(43)

2020年(62)

2014年(3)

2013年(9)

分类: Oracle

2020-06-10 16:18:20

接PART2:

2.5 探索性能杀手FILTER

2.5.1性能杀手FILTER形成机制

为什么会形成FILTER操作?(多子节点,单子节点纯粹过滤操作

  FILTER形成于查询转换期间,如果对于子查询无法进行 unnest转换来消除子查询,则会走FILTER,走FILTER说明子查询是受外表结果驱动,类似循环操作!很显然,如果驱动的次数越多,效率越低!

  查询转换是能够生成高效SQL执行计划的重要步骤,查询转换不能做好,后面的很多执行路径就没法走了。掌握查询转换机制,对如何写高效的SQL,调优SQL至关重要,了解的越深,对CBO就越了解。下面是CBO组件图,熟悉对应组件是SQL优化必须的内容:



1)FILTER什么时候高效?

  FILTER本身会构建HASH表来保存输入/输出对,以备后续减少子查询执行次数,这是与纯粹NESED LOOPS操作的典型区别,比如from a where a.statusIn(select b.staus from b) 如果status前面已经查过,则后续不需要再次执行子查询,而是直接从保存的HASH表中获取结果,这样减少了子查询执行次数,从而提高效率。也就是说,如果子查询关联条件的重复值很多,FILTER还是有一定的优势,否则就是灾难!

2)FILTERpush_subq hints

  如果走FILTER则子查询是受制于子查询外结果集驱动,也就是子查询是最后执行,但是实际有时候子查询应该先执行效率更好,这时候可以使用push_subq hints

2.5.2性能杀手FILTER形成机制实例

简化前面的语句关键部分如下:


Oracle内部改写如下,无法unnest,如果unnest


执行计划如下:


  从执行计划里可以看到,FILTER多子节点一般有如下特点:

1) 自动生成的绑定变量:B1,因为需要执行循环操作

2) 转为EXISTS

  所以以后看到有自动生成的绑定变量的执行计划,都是类似FILTER的操作,比如标量子查询,UPDATE关联子查询,优化的话,都需要干掉(类)FILTER来优化。

这里的例子其实是一个CBO的限制:

含有OR的子查询,经常性无法unnest,Oracle大多无法给转换成UNION/UNION ALL形式的查询

所以,针对这样的语句优化:

    1.改写为UNION/UNION ALL形式

    2.根据语义、业务含义彻底重写

  也就是说,需要重构查询,消除FILTER!慢的根源如下,这里7万多行,只执行了116行打印的执行计划!Id=3~6的执行次数依赖于Id=2的结果行数,id=3~6全表扫描次数太多。


未完待续,见PART4:


阅读(1256) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~