15

一个表查询

索引

全表扫描


两个表关联

小表驱动大表 


一般引起性能问题的多是复杂的子查询


select  后面的查询  官方叫法就叫标量子查询

select a.owner,a.object_name,(select object_type from test2 where object_id=a.object_id) object_type from test a 

a 表传值多少次test2就需要查询多少次,所以test2必须建立索引。


作业! 1 .  写一个脚本把标量子查询抓出来,标量自查询需要改成左连接、右连接。 如果不能改成外连接的情况在连接列建立索引,但是建立索引时需要防止回标。

            提醒,有标量的是不是depth=1并且 cost大于=2         查看 :V$SQL_PLAN



今天讲where后面的子查询     in   not in  exists  not  exists   叫半连接/反连接,很有可能产生filter。

filter 的缺点 ,无法改驱动表。  作为一个dba无法改优化方案那就表示不可控制。 所以尽量避免产生filter。


在生产反正中是否经常遇到

select ... from a, v_b where a.id=v_b.id;

比喻说a 有100条,v_b中有100w,肯定死

但是如果a能传值给v_b这个时候不死。类似谓词推入。关键看有没有传值进去。没传走hash,传进去了走nl。

那怎么判断有没有传值进去,

 SELECT to_char(wmsys.wm_concat(a.TABLE_NAME))
  FROM user_tables a, dba_objects b
 WHERE a.TABLE_NAME = b.OBJECT_NAME
   AND b.OWNER = 'HBTELEPS'
   AND B.OBJECT_TYPE = 'TABLE'; 

当SQL语句中有内联视图(in-line view,内联视图就是在from后面有select子查询)
或者SQL语句中有用 create view...创建的视图,CBO会将内联视图/视图给展开,进行等价的改写,这个过程就叫做视图合并。如果没有发生视图合并,在执行计划中,我们可以看到VIEW关键字。

其实就是看执行计划里面有没有view关键字。

究竟视图合并会对性能带来什么影响呢?

一个sql语句执行计划有且仅有一个是最优的。

视图合并后执行计划就混乱了,

用一个hint让视图不合并,

SELECT /*+ no_merge(a) */ to_char(wmsys.wm_concat(a.TABLE_NAME))
  FROM user_tables a, dba_objects b
 WHERE a.TABLE_NAME = b.OBJECT_NAME
   AND b.OWNER = 'HBTELEPS'
   AND B.OBJECT_TYPE = 'TABLE';

用no_merge 告诉oracle优化器不要对a进行视图合并

这两个视图不合并走hash,hash不传值,视图不合并是不是意味着视图一定会当成一个整体。 当成了整体是不是可以传值进去呢,有些视图可以,有些视图不可以。

那些可以?那些不可以呢?

select /*+ no_merge(a) */  from v_a,v_b,c where v_a=c.id and c.xx=v_b.xx;

v_a 1w
v_b 10w
c 100

我不管你跑多久,我先把你视图单独跑,看你视图是不是产生视图合并。

select /*+ no_merge(v_a) no_merge(v_b) */  from v_a,v_b,c where v_a=c.id and c.xx=v_b.xx;

---------------------------------------------------

select * from v_a,v_b,c where v_a=c.id and c.xx=v_b.xx;
v_a 1w
v_b 10w
c 100

如果v_a单独跑还需要很长时间,那么直接处理v_a视图。


什么样的视图不能被合并呢?

1.子查询有 ROWNUM
2.子查询有 CUBE,ROLLUP
3.子查询有 UNION, UNION ALL
4. START WITH ,CONNECT BY (树形查询)


in 和exists等价改写

select ename, deptno
   from emp
  where deptno in (select  deptno
                     from dept
                    where dname = 'CHICAGO'
                   union
                   select deptno from dept where loc = 'CHICAGO');

-------------------------------------------------------------------------------------------------------------------------------------------

select ename, deptno
   from emp
  where deptno in (select /*+ unnest */ deptno
                     from dept
                    where dname = 'CHICAGO'
                   union
                   select deptno from dept where loc = 'CHICAGO');


----------------------------------------------------------------------------------------------------------------------------------------------

select ename, deptno
   from emp
  where exists  (select  1
                     from dept
                    where  emp.deptno=dept.deptno and  dname = 'CHICAGO'
                   union
                   select 1from dept where  emp.deptno=dept.deptno   loc = 'CHICAGO');

-------------------------------------------------------------------------------------------------------------------------------------------

 select ename, deptno
   from emp
  where exists (select 1 from (select /*+ unnest */ deptno
                     from dept
                    where dname = 'CHICAGO'
                   union
                   select deptno from dept where loc = 'CHICAGO') a where a.deptno=emp.deptno ); 
-----------------------------------------------------------------------------------------------------------------------------------------

/*+ unnest */   不产生filter的意思。











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值