table get 主键 select * 不用回表
table scan 范围扫描 当range(MIN,MIN, MIN ; MAX, MAX, MAX)代表全表扫描
table lookup 全局索引回表
以下读sql优化核心思想进行提炼
全局索引和局部索引
全局索引:索引表中一个分区对应多个分区数据,TABLE LOOKUP 算子中就会包含一次 RPC 操作到远端机器上去获取主表数据。因此全局索引相比局部索引有更高的维护代价
NESTED LOOPS :
1、驱动表返回一行数据,通过连接列传值给被驱动表,驱动表返回多少行,被驱动表就要被扫描多少次。
2、嵌套循环驱动表应该返回少量数据
3、嵌套循环被驱动表必须走索引。如果嵌套循环被驱动表的连接列没包含在索引中,那么被驱动表就只能走全表扫描,而且是反复多次全表扫描
4、两表关联返回少量数据才能走嵌套循环
5、嵌套循环被驱动表的连接列基数应该很高
hint:/*+ use_nl(d,e) leading(e) */
use_nl(d,e)表示让两表走嵌套循环,在书的时候,如果表有别名中一定要使用别名,否不生效;如果表没有别名中就直接使用表名。
不能修改驱动表的情况:
1、当两表使用外连接进行关联,如果执行计划是走嵌套循环,那么这时无法更改驱动表,驱动表会被固定为主表,(left join,right join,full outer join )
2、如果外连接中从表有过滤条件,那么此时外连接会变为内连接,hint就会生效
例子:
select /*+ leading(e) use_nl(d,e) */ * from dept d left join emp e on d.deptno = e.deptno where e.sal < 3000;
1、判断两表走不走NESTED LOOPS
两表关联走不走NL 是看两个表关联之后返回的数据量多少?还是看驱动表返回的数据量多少?
如果两个表是1∶N 关系,驱动表为1,被驱动表为N 并且N 很大,这时即使驱动表返回数据量很少,也不能走嵌套循环,因为两表关联之后返回的数据量会很多。
所以断两表关联是否应该走NL 应该直接查看两表关联之后返回的数据量,如果两表关联之后返回的数据量少,可以走NL;返回的数据量多,应该走HASH 连接。
2、大表是否可以当嵌套循环(NL)驱动表?
可以,如果大表过滤之后返回的数据量很少就可以当NL 驱动表。