【Oracle Hint】Oracle Hint学习笔记【一】

一、Oracle Hint的一些基本概念

  • Oracle数据库中的优化器又叫查询优化器(Query Optimizer)。

    它是SQL分析和执行的优化工具,它负责生成、制定SQL的执行计划。

    Oracle的优化器有两种,基于规则的优化器(RBO)与基于代价的优化器(CBO)

    ​ RBO: Rule-Based Optimization 基于规则的优化器

    ​ CBO: Cost-Based Optimization 基于代价的优化器

  • CBO(基于代价的优化器)在绝大多数情况下它会选择正确的优化器,但有时它也会选择很差的执行计划。

  • 在Oracle 中,通过为语句添加 Hints(提示)来实现干预优化器优化的目的。

  • Oracle Hints的语法:

    {DELETE|INSERT|SELECT|UPDATE} /*+ hint [text] [hint[text]]... */
    

    或者

    {DELETE|INSERT|SELECT|UPDATE} --+ hint [text] [hint[text]]...
    
    • Hints只应用在它们所在sql语句块(statement block,由select、update、delete关键字标识)上,对其它SQL语句或语句的其它部分没有影响。如:对于使用union操作的2个sql语句,如果只在一个sql语句上有Hints,则该Hints不会影响另一个sql语句。
    • “+”号表示该注释是一个Hints,该加号必须立即跟在”/*”的后面,中间不能有空格。
    • "hint"是下面介绍的具体提示之一,如果包含多个提示,则每个提示之间需要用一个或多个空格隔开。
    • 如果在查询中指定了表别名,那么提示必须也使用表别名。
Hint的分类常见Hint关键字
1优化器模式ALL_ROWS(CBO)、FIRST_ROWS(CBO)、RULE(RBO)
2访问路径(是全表扫描,还是索引扫描)FULL、INDEX、NO_INDEX、INDEX_JOIN等
3表之间的连接类型HASH JOIN 、MERGE JOIN 、NESTED LOOP
4表之间的连接顺序USE_MERGE、USE_NL、USE_HASH
5语句的并行程度PARALLEL、FACT 、NO_FACT、 MERGE 、NO_MERGE等

二、表之间的连接类型

1. NESTED LOOP 一般用在连接的表中有索引,并且索引选择性较好的时候

对于被连接的数据子集较小的情况,嵌套循环连接是个较好的选择。在嵌套循环中,内表被外表驱动,外表返回的每一行都要在内表中检索找到与它匹配的行,因此整个查询返回的结果集不能太大(大于1 万不适合),要把返回子集较小表的作为外表(CBO 默认外表是驱动表),而且在内表的连接字段上一定要有索引。

可以用ORDERED 提示来改变CBO默认的驱动表,使用USE_NL(table_name1 table_name2)强制CBO 执行嵌套循环连接。

USE_NL(A B) 内外表,由form后的表顺序决定,存在LOADING时,以LOADING指定为准

USE_NL(A) A为内表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ya9Z9MOn-1643026474562)(Oracle Hint学习笔记.assets/1642989717081.png)]

2. HASH JOIN 一般用在两个表的数据量差别很大的时候

散列连接是CBO 做大数据集连接时的常用方式,优化器使用两个表中较小的表(或数据源)利用连接键在内存中建立散列表,然后扫描较大的表并探测散列表,找出与散列表匹配的行。

这种方式适用于较小的表完全可以放于内存中的情况,这样总成本就是访问两个表的成本之和。但是在表很大的情况下并不能完全放入内存,这时优化器会将它分割成若干不同的分区,不能放入内存的部分就把该分区写入磁盘的临时段,此时要有较大的临时段从而尽量提高I/O 的性能。

可以用USE_HASH(table_name1 table_name2)提示来强制使用散列连接。使用散列连接HASH_AREA_SIZE 初始化参数必须足够的大,如果是9i,Oracle建议使用SQL工作区自动管理。

Hash Join的执行计划第1个是hash表(build table),第2个探查表(probe table),一般不叫内外表,nested loop才有内外表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mjG0MQEo-1643026474564)(Oracle Hint学习笔记.assets/1359475771_5689.png)]

3. SORT MERGE JOIN 用在没有索引,并且数据已经排序的情况

merge join需要首先对两个表按照关联的字段进行排序,分别从两个表中取出一行数据进行匹配,如果合适放入结果集;不匹配将较小的那行丢掉继续匹配另一个表的下一行,依次处理直到将两表的数据取完。merge join的很大一部分开销花在排序上,也是同等条件下差于hash join的一个主要原因。可以使用USE_MERGE(table_name1 table_name2)来强制使用排序合并连接.

其他关键字说明

  • LEADING 在一个多表关联的查询中,该Hint指定由哪个表作为驱动表,告诉优化器首先要访问哪个表上的数据。

    select /*+leading(t1,t) */ 
    	* 
    from scott.dept t,scott.emp t1 
    where t.deptno=t1.deptno;
    
  • ORDERED 按照From后面的表的顺序来选择驱动表,Oracle 建议在选择驱动表上使用Leading,它更灵活一些。

三、实际执行测试

1.NESTED LOOP

1.1 oracle 使用use_nl(a b)时,顺序use_nl(a b) use_nl(b a) 不会影响执行计划

1.2 ordered use_nl(a) 强制指定内表,括号中的表一定为内表(数据量大的表)

1.3 ordered use_nl(a b) 强制指定内外表,如果没有join,from后的第一个表为外表,第二个表为内表

​ ordered use_nl(a b) 强制指定内外表,如果有join,左连接时左表为外表,

​ 右连接时右表为外表,

​ 内连接时第一个表为外表,

​ 外连接时,分别以第一\二个表为外表,做一次union

1.4 LEADING(a) 强制指定外表(驱动表)

建表sql

--drop table tmpa;
--drop table tmpb;
create table tmpa as 
	select rownum a, object_id b, OBJECT_NAME c from DBA_objects where rownum<=10000;
create table tmpb as 
	select rownum a, object_id b, OBJECT_NAME c from DBA_objects where rownum<=10;
CREATE UNIQUE INDEX tmpa_idx_1 ON tmpa (a,b);
CREATE UNIQUE INDEX tmpb_idx_1 ON tmpa (a,b);
1.1 use_nl(a b) 、use_nl(b a)
SELECT /*+use_nl(a b) */ * FROM tmpa a, tmpb b WHERE a.a = b.a;
SELECT /*+use_nl(b a) */ * FROM tmpa a, tmpb b WHERE a.a = b.a;
操作对象优化器成本基数字节
SELECT STATEMENTALL_ROWS2310400
NESTED LOOPS[NULL]2310400
NESTED LOOPS[NULL]2310400
TABLE ACCESS (FULL)TMPBANALYZED310140
INDEX (RANGE SCAN)TMPA_IDX_1ANALYZED110
TABLE ACCESS (BY INDEX ROWID)TMPAANALYZED2126
SELECT /*+use_nl(a b) */ * FROM tmpb b LEFT JOIN tmpa a on b.a =a.a ;
SELECT /*+use_nl(b a) */ * FROM tmpb b LEFT JOIN tmpa a on b.a =a.a ;
SELECT /*+use_nl(b a) */ * FROM tmpa a RIGHT JOIN tmpb b ON b.a =a.a ;
SELECT /*+use_nl(a b) */ * FROM tmpa a RIGHT JOIN tmpb b ON b.a =a.a ;
操作对象优化器成本基数字节
SELECT STATEMENTALL_ROWS2310400
NESTED LOOPS (OUTER)[NULL]2310400
TABLE ACCESS (FULL)TMPBANALYZED310140
TABLE ACCESS (BY INDEX ROWID BATCHED)TMPAANALYZED2126
INDEX (RANGE SCAN)TMPA_IDX_1ANALYZED110
SELECT /*+use_nl(b a) */ * FROM tmpa a LEFT JOIN tmpb b ON b.a =a.a ;
SELECT /*+use_nl(a b) */ * FROM tmpa a LEFT JOIN tmpb b ON b.a =a.a ;
操作对象优化器成本基数字节
SELECT STATEMENTALL_ROWS1085810000400000
NESTED LOOPS (OUTER)[NULL]1085810000400000
TABLE ACCESS (FULL)TMPAANALYZED1510000260000
TABLE ACCESS (FULL)TMPBANALYZED1114
1.2 ordered use_nl(a) 强制指定驱动表
SELECT /*+ordered use_nl(a) */ * FROM tmpa a, tmpb b WHERE a.a = b.a;
操作对象优化器成本基数字节
SELECT STATEMENTALL_ROWS1810400
HASH JOIN[NULL]1810400
TABLE ACCESS (FULL)TMPAANALYZED1510000260000
TABLE ACCESS (FULL)TMPBANALYZED310140
SELECT /*+ordered use_nl(b) */ * FROM tmpa a, tmpb b WHERE a.a = b.a;
操作对象优化器成本基数字节
SELECT STATEMENTALL_ROWS1085810400
NESTED LOOPS[NULL]1085810400
TABLE ACCESS (FULL)TMPAANALYZED1510000260000
TABLE ACCESS (FULL)TMPBANALYZED1114
SELECT /*+ordered use_nl(a) */ * FROM tmpb b, tmpa a WHERE a.a = b.a;
操作对象优化器成本基数字节
SELECT STATEMENTALL_ROWS2310400
NESTED LOOPS[NULL]2310400
NESTED LOOPS[NULL]2310400
TABLE ACCESS (FULL)TMPBANALYZED310140
INDEX (RANGE SCAN)TMPA_IDX_1ANALYZED110
TABLE ACCESS (BY INDEX ROWID)TMPAANALYZED2126
SELECT /*+ordered use_nl(b) */ * FROM tmpb b, tmpa a WHERE a.a = b.a;
操作对象优化器成本基数字节
SELECT STATEMENTALL_ROWS1810400
HASH JOIN[NULL]1810400
NESTED LOOPS[NULL]1810400
NESTED LOOPS[NULL]300
STATISTICS COLLECTOR[NULL]300
TABLE ACCESS (FULL)TMPBANALYZED310140
INDEX (RANGE SCAN)TMPA_IDX_1ANALYZED000
TABLE ACCESS (BY INDEX ROWID)TMPAANALYZED15126
TABLE ACCESS (FULL)TMPAANALYZED1510000260000
SELECT /*+ordered use_nl(a) */ * FROM tmpa a RIGHT join tmpb b on a.a = b.a;
SELECT /*+ordered use_nl(a) */ * FROM tmpb b left join tmpa a on a.a = b.a;
操作对象优化器成本基数字节
SELECT STATEMENTALL_ROWS2310400
NESTED LOOPS (OUTER)[NULL]2310400
TABLE ACCESS (FULL)TMPBANALYZED310140
TABLE ACCESS (BY INDEX ROWID BATCHED)TMPAANALYZED2126
INDEX (RANGE SCAN)TMPA_IDX_1ANALYZED110
SELECT /*+ordered use_nl(b) */ * FROM tmpa a RIGHT join tmpb b on a.a = b.a;
SELECT /*+ordered use_nl(b) */ * FROM tmpb b left join tmpa a on a.a = b.a;
操作对象优化器成本基数字节
SELECT STATEMENTALL_ROWS1810400
HASH JOIN (OUTER)[NULL]1810400
NESTED LOOPS (OUTER)[NULL]1810400
STATISTICS COLLECTOR[NULL]300
TABLE ACCESS (FULL)TMPBANALYZED310140
TABLE ACCESS (BY INDEX ROWID BATCHED)TMPAANALYZED15126
INDEX (RANGE SCAN)TMPA_IDX_1ANALYZED000
TABLE ACCESS (FULL)TMPAANALYZED1510000260000
1.3 ordered use_nl(a b)
SELECT /*+ordered use_nl(a b) */ * FROM tmpa a, tmpb b WHERE a.a = b.a;
SELECT /*+ordered use_nl(b a) */ * FROM tmpa a, tmpb b WHERE a.a = b.a;
操作对象优化器成本基数字节
SELECT STATEMENTALL_ROWS1085810400
NESTED LOOPS[NULL]1085810400
TABLE ACCESS (FULL)TMPAANALYZED1510000260000
TABLE ACCESS (FULL)TMPBANALYZED1114
SELECT /*+ordered use_nl(a b) */ * FROM tmpb b, tmpa a WHERE a.a = b.a;
SELECT /*+ordered use_nl(b a) */ * FROM tmpb b, tmpa a WHERE a.a = b.a;
操作对象优化器成本基数字节
SELECT STATEMENTALL_ROWS2310400
NESTED LOOPS[NULL]2310400
NESTED LOOPS[NULL]2310400
TABLE ACCESS (FULL)TMPBANALYZED310140
INDEX (RANGE SCAN)TMPA_IDX_1ANALYZED110
TABLE ACCESS (BY INDEX ROWID)TMPAANALYZED2126
SELECT /*+ordered use_nl(a b) */ * FROM tmpa a RIGHT join tmpb b on a.a = b.a;
SELECT /*+ordered use_nl(b a) */ * FROM tmpa a RIGHT join tmpb b on a.a = b.a;
SELECT /*+ordered use_nl(a b) */ * FROM tmpb b left join tmpa a on a.a = b.a;
SELECT /*+ordered use_nl(b a) */ * FROM tmpb b left join tmpa a on a.a = b.a;
操作对象优化器成本基数字节
SELECT STATEMENTALL_ROWS2310400
NESTED LOOPS (OUTER)[NULL]2310400
TABLE ACCESS (FULL)TMPBANALYZED310140
TABLE ACCESS (BY INDEX ROWID BATCHED)TMPAANALYZED2126
INDEX (RANGE SCAN)TMPA_IDX_1ANALYZED110
1.4 LEADING 指定驱动表
SELECT /*+LEADING(a) use_nl(b) */ * FROM tmpa a, tmpb b WHERE a.a = b.a;
SELECT /*+LEADING(a) use_nl(b) */ * FROM tmpb b, tmpa a WHERE a.a = b.a;
SELECT /*+LEADING(a) use_nl(b,a) */ * FROM tmpa a, tmpb b WHERE a.a = b.a;
SELECT /*+LEADING(a) use_nl(a,b) */ * FROM tmpa a, tmpb b WHERE a.a = b.a;
SELECT /*+LEADING(a) use_nl(b,a) */ * FROM tmpb b, tmpa a WHERE a.a = b.a;
SELECT /*+LEADING(a) use_nl(a,b) */ * FROM tmpb b, tmpa a WHERE a.a = b.a;
操作对象优化器成本基数字节
SELECT STATEMENTALL_ROWS1085810400
NESTED LOOPS[NULL]1085810400
TABLE ACCESS (FULL)TMPAANALYZED1510000260000
TABLE ACCESS (FULL)TMPBANALYZED1114
SELECT /*+LEADING(b) use_nl(a) */ * FROM tmpa a, tmpb b WHERE a.a = b.a;
SELECT /*+LEADING(b) use_nl(a) */ * FROM tmpb b, tmpa a WHERE a.a = b.a;
SELECT /*+LEADING(b) use_nl(a,b) */ * FROM tmpa a, tmpb b WHERE a.a = b.a;
SELECT /*+LEADING(b) use_nl(b,a) */ * FROM tmpa a, tmpb b WHERE a.a = b.a;
SELECT /*+LEADING(b) use_nl(b,a) */ * FROM tmpb b, tmpa a WHERE a.a = b.a;
SELECT /*+LEADING(b) use_nl(a,b) */ * FROM tmpb b, tmpa a WHERE a.a = b.a;
操作对象优化器成本基数字节
SELECT STATEMENTALL_ROWS2310400
NESTED LOOPS[NULL]2310400
NESTED LOOPS[NULL]2310400
TABLE ACCESS (FULL)TMPBANALYZED310140
INDEX (RANGE SCAN)TMPA_IDX_1ANALYZED110
TABLE ACCESS (BY INDEX ROWID)TMPAANALYZED2126
--此时没生效 仍然以b为外部表
SELECT /*+LEADING(a) use_nl(b) */ * FROM tmpa a RIGHT JOIN  tmpb b on a.a = b.a;
SELECT /*+LEADING(a) use_nl(b) */ * FROM tmpb b left JOIN tmpa a  on a.a = b.a;
操作对象优化器成本基数字节
SELECT STATEMENTALL_ROWS1810400
HASH JOIN (OUTER)[NULL]1810400
NESTED LOOPS (OUTER)[NULL]1810400
STATISTICS COLLECTOR[NULL]300
TABLE ACCESS (FULL)TMPBANALYZED310140
TABLE ACCESS (BY INDEX ROWID BATCHED)TMPAANALYZED15126
INDEX (RANGE SCAN)TMPA_IDX_1ANALYZED000
TABLE ACCESS (FULL)TMPAANALYZED1510000260000
SELECT /*+LEADING(b) use_nl(a) */ * FROM tmpa a RIGHT JOIN  tmpb b on a.a = b.a;
SELECT /*+LEADING(b) use_nl(a) */ * FROM tmpb b left JOIN tmpa a  on a.a = b.a;
操作对象优化器成本基数字节
SELECT STATEMENTALL_ROWS2310400
NESTED LOOPS (OUTER)[NULL]2310400
TABLE ACCESS (FULL)TMPBANALYZED310140
TABLE ACCESS (BY INDEX ROWID BATCHED)TMPAANALYZED2126
INDEX (RANGE SCAN)TMPA_IDX_1ANALYZED110

2. HASH JOIN

2.1hash_join(a) hash_join(a,b)
SELECT /*+hash_join(a) */ * FROM tmpb b , tmpa a  WHERE a.a = b.a;
SELECT /*+hash_join(b) */ * FROM tmpb b , tmpa a  WHERE a.a = b.a;
SELECT /*+hash_join(a,b) */ * FROM tmpb b , tmpa a  WHERE a.a = b.a;
SELECT /*+hash_join(b,a) */ * FROM tmpb b , tmpa a  WHERE a.a = b.a;
操作对象优化器成本基数字节
SELECT STATEMENTALL_ROWS1810400
HASH JOIN[NULL]1810400
NESTED LOOPS[NULL]1810400
NESTED LOOPS[NULL]300
STATISTICS COLLECTOR[NULL]300
TABLE ACCESS (FULL)TMPBANALYZED310140
INDEX (RANGE SCAN)TMPA_IDX_1ANALYZED000
TABLE ACCESS (BY INDEX ROWID)TMPAANALYZED15126
TABLE ACCESS (FULL)TMPAANALYZED1510000260000
SELECT /*+hash_join(a) */ * FROM tmpb b left JOIN tmpa a  on a.a = b.a;
SELECT /*+hash_join(b) */ * FROM tmpb b left JOIN tmpa a  on a.a = b.a;
SELECT /*+hash_join(a) */ * FROM tmpa a right JOIN tmpb b  on a.a = b.a;
SELECT /*+hash_join(b) */ * FROM tmpa a right JOIN tmpb b  on a.a = b.a;
SELECT /*+hash_join(a,b) */ * FROM tmpb b left JOIN tmpa a  on a.a = b.a;
SELECT /*+hash_join(a,b) */ * FROM tmpa a right JOIN tmpb b  on a.a = b.a;
SELECT /*+hash_join(b,a) */ * FROM tmpb b left JOIN tmpa a  on a.a = b.a;
SELECT /*+hash_join(b,a) */ * FROM tmpa a right JOIN tmpb b  on a.a = b.a;
操作对象优化器成本基数字节
SELECT STATEMENTALL_ROWS1810400
HASH JOIN (OUTER)[NULL]1810400
NESTED LOOPS (OUTER)[NULL]1810400
STATISTICS COLLECTOR[NULL]300
TABLE ACCESS (FULL)TMPBANALYZED310140
TABLE ACCESS (BY INDEX ROWID BATCHED)TMPAANALYZED15126
INDEX (RANGE SCAN)TMPA_IDX_1ANALYZED000
TABLE ACCESS (FULL)TMPAANALYZED1510000260000

待补充

3. SORT MERGE JOIN

待补充

附录

环境说明:Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.10.0.0.0

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值