Oracle Hint 语法详解

2024-04-22 07:04
文章标签 oracle 详解 语法 hint

本文主要是介绍Oracle Hint 语法详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

什么是Hint

Hint 是 Oracle 提供的一种 SQL 语法,它允许用户在 SQL 语句中插入相关的语法,从而影响 SQL 的执行方式。
因为 Hint 的特殊作用,所以对于开发人员不应该在代码中使用它,Hint 更像是 Oracle 提供给 DBA 用来分析诊断问题的工具 。

导致 Hint 失效的原因

在使用 Hint 时需要注意的一点是,并非任何时刻 Hint 都起作用。 导致 HINT 失效的原因有如下 2 点:

(1) 如果 CBO 认为使用 Hint 会导致错误的结果时,Hint 将被忽略。
(2) 如果表中指定了别名,那么 Hint 中也必须使用别名,否则 Hint 也会忽略。

SQL>Select /*+full(a)*/ * from t a; -- 使用 hint
SQL>Select /*+full(t) */ * from t a; --不使用 hint

Hint 使用规则及注意事项

1、hint 其实是一种注释,如果目标 SQL 的文本出现了 hint,则优化器会选择 hint 的执行计划,而不会考虑
最优的执行计划,但前提是这个 HINT 是可选的执行计划之一。

2、hint 的用法:必须紧随关键字 select、insert、update,delete 后,hint 中第一个星号和加号之间不能有空格,一般写法 /*+ gather_plan_statistics */,如果有两个 hint,用空格隔开。hint 中指定具体对象时,不能带上该对象所在 schema 的名称。即使该 sql 文本中已经有对应的 schema的名称。

在 hint 中指定具体表名时,如果该表在对应 sql 文本中有别名,则应该使用该表的别名。oracle 数据库中的query block 是指一个语义上完整的查询语句,hint 生效范围仅限于它本身所在的 query block。如果一个语句有子查询,那么主查询的 hint 只能作用于主查询,如果想让 Hint 作用于子查询,那么 hint 要加在子查询上。

Hint 的功能划分

可以分成如下几类:
在这里插入图片描述

Hint使用示例

1、和优化器相关的 Hint
SQL> select /*+ all_rows */ * from scott.emp;
SQL> select /*+ first_rows(20) */ * from scott.emp;
SQL> select /*+ rule */ * from scott.emp;
2、访问路径相关的 Hint

这一部分 hint 将直接影响 SQL 的执行计划,所以在使用时需要特别小心。 该类 Hint 对 DBA 分析 SQL 性能
非常有帮助,DBA 可以让 SQL 使用不同的 Hint 得到不同的执行计划,通过比较不同的执行计划来分析当前 SQL性能。

FULL Hint
该 Hint 告诉优化器对指定的表通过全表扫描的方式访问数据。
示例:

SQL> select /*+full(emp) */ * from emp;

要注意,如果表有别名,在 hint 里也要用别名, 这点在前面已经说明。

INDEX Hint
Index hint 告诉优化器对指定的表通过索引的方式访问数据,当访问索引会导致结果集不完整时,优化器会忽略这个 Hint。
示例:

SQL> select /*+index(emp index_emp) */ * from emp where id>1;

谓词里有索引字段,才会用索引。

NO_INDEX Hint
No_index hint 告诉优化器对指定的表不允许使用索引。
示例:

SQL> select /*+no_index(emp index_emp) */ * from emp where id>1;

INDEX_DESC Hint
该 Hint 告诉优化器对指定的索引使用降序方式访问数据,当使用这个方式会导致结果集不完整时,优化器将忽略这个索引。
示例:

SQL> select /*+index_desc(emp index_emp) */ * from emp where id>1;

INDEX_COMBINE Hint
该 Hint 告诉优化器强制选择位图索引,当使用这个方式会导致结果集不完整时,优化器将忽略这个 Hint。
示例:

SQL> select /*+ index_combine(emp index_bm) */ * from emp;

INDEX_FFS Hint
该 hint 告诉优化器以 INDEX_FFS(INDEX Fast Full Scan)的方式访问数据。当使用这个方式会导致结果集不完整时,优化器将忽略这个 Hint。
示例:

SQL> select /*+ index_ffs(emp index_emp) */ id from emp where id>0;

INDEX_JOIN Hint
索引关联,当谓词中引用的列上都有索引时,可以通过索引关联的方式来访问数据。
示例:

SQL> select /*+ index_join(emp index_emp index_bm) */ * from emp where id>0 and name='tom ';

INDEX_SS Hint
该 Hint 强制使用 index skip scan 的方式访问索引,从 Oracle 9i 开始引入这种索引访问方式,当在一个联合索引中,某些谓词条件并不在联合索引的第一列时(或者谓词并不在联合索引的第一列时),可以通过 index
skip scan 来访问索引获得数据。 当联合索引第一列的唯一值很小时,使用这种方式比全表扫描效率要高。当
使用这个方式会导致结果集不完整时,优化器将忽略这个 Hint。
示例:

SQL> select /*+ index_ss(emp index_union) */ * from emp where id>0;
3、表关联顺序的 Hint

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

示例:

SQL> select /*+leading(t1,t) */ * from scott.dept t,scott.emp t1 where t.deptno=t1.deptno;SQL> select /*+leading(t,t1) */ * from scott.dept t,scott.emp t1 where t.deptno=t1.deptno;
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Ti
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 812 | 6 (17)| 00
| 1 | MERGE JOIN | | 14 | 812 | 6 (17)| 00
| 2 | TABLE ACCESS BY INDEX ROWID| DEPT | 4 | 80 | 2 (0)| 00
| 3 | INDEX FULL SCAN | PK_DEPT | 4 | | 1 (0)| 00
|* 4 | SORT JOIN | | 14 | 532 | 4 (25)| 00
| 5 | TABLE ACCESS FULL | EMP | 14 | 532 | 3 (0)| 00
--------------------------------------------------------------------------------

ORDERED Hint
该 hint 告诉 Oracle 按照 From 后面的表的顺序来选择驱动表,Oracle 建议在选择驱动表上使用 Leading,它更灵活一些。

SQL> select /*+ordered */ * from scott.dept t,scott.emp t1 where t.deptno=t1.deptno;
4、表关联操作的 Hint

USE_HASH,USE_NL,USE_MERGE hint
这三种关联方式是多表关联中主要使用的关联方式。 通常来说,当两个表都比较大时,Hash Join 的效率要高于嵌套循环(nested loops)的关联方式。

Hash join 的工作方式是将一个表(通常是小一点的那个表)做 hash 运算,将列数据存储到 hash 列表中,从另一个表中抽取记录,做 hash 运算,到 hash 列表中找到相应的值,做匹配。

Nested loops 工作方式是从一张表中读取数据,访问另一张表(通常是索引)来做匹配,nested loops 适用的场合是当一个关联表比较小的时候,效率会更高。

Merge Join 是先将关联表的关联列各自做排序,然后从各自的排序表中抽取数据,到另一个排序表中做匹配,因为 merge join 需要做更多的排序,所以消耗的资源更多。 通常来讲,能够使用 merge join 的地方,hash
join 都可以发挥更好的性能。

USE_HASH,USE_NL,USE_MERGE 这三种hint 就是告诉优化器使用哪种关联方式。
示例如下:

SQL> select /*+use_hash(t,t1) */ * from scott.dept t,scott.emp t1 where t.deptno=t1.deptno;
SQL> select /*+use_nl(t,t1) */ * from scott.dept t,scott.emp t1 where t.deptno=t1.deptno;
SQL> select /*+use_merge(t,t1) */ * from scott.dept t,scott.emp t1 where t.deptno=t1.deptno;

NO_USE_HASH,NO_USE_NL,NO_USE_MERGE HINT
分别禁用对应的关联方式。
示例:

SQL> select /*+no_use_merge(t,t1) */ * from scott.dept t,scott.emp t1 where t.deptno=t1.deptno;
SQL> select /*+no_use_nl(t,t1) */ * from scott.dept t,scott.emp t1 where t.deptno=t1.deptno;
SQL> select /*+no_use_hash(t,t1) */ * from scott.dept t,scott.emp t1 where t.deptno=t1.deptno;
5、并行执行相关的 Hint

PARALLEL HINT
指定 SQL 执行的并行度,这个值会覆盖表自身设定的并行度,如果这个值为 default,CBO 使用系统参数值。
示例:

SQL> select /*+parallel(t 4) */ * from scott.dept t;

NO_PARALLEL HINT
在 SQL 中禁止使用并行。
示例:

SQL> select /*+ no_parallel(t) */ * from scott.dept t;
6、其他方面的一些 Hint

APPEND HINT
提示数据库以直接加载的方式(direct load)将数据加载入库。
示例:

Insert /*+append */ into t as select * from all_objects;

这个 hint 用的比较多。 尤其在插入大量的数据,一般都会用此 hint。

DYNAMIC_SAMPLING HINT
提示 SQL 执行时动态采样的级别。 这个级别从 0-10,它将覆盖系统默认的动态采样级别。
示例:

SQL> select /*+ dynamic_sampling(t 2) */ * from scott.emp t where t.empno>0;

这篇关于Oracle Hint 语法详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/925101

相关文章

MySQL中的分组和多表连接详解

《MySQL中的分组和多表连接详解》:本文主要介绍MySQL中的分组和多表连接的相关操作,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录mysql中的分组和多表连接一、MySQL的分组(group javascriptby )二、多表连接(表连接会产生大量的数据垃圾)MySQL中的

Java 实用工具类Spring 的 AnnotationUtils详解

《Java实用工具类Spring的AnnotationUtils详解》Spring框架提供了一个强大的注解工具类org.springframework.core.annotation.Annot... 目录前言一、AnnotationUtils 的常用方法二、常见应用场景三、与 JDK 原生注解 API 的

redis中使用lua脚本的原理与基本使用详解

《redis中使用lua脚本的原理与基本使用详解》在Redis中使用Lua脚本可以实现原子性操作、减少网络开销以及提高执行效率,下面小编就来和大家详细介绍一下在redis中使用lua脚本的原理... 目录Redis 执行 Lua 脚本的原理基本使用方法使用EVAL命令执行 Lua 脚本使用EVALSHA命令

SpringBoot3.4配置校验新特性的用法详解

《SpringBoot3.4配置校验新特性的用法详解》SpringBoot3.4对配置校验支持进行了全面升级,这篇文章为大家详细介绍了一下它们的具体使用,文中的示例代码讲解详细,感兴趣的小伙伴可以参考... 目录基本用法示例定义配置类配置 application.yml注入使用嵌套对象与集合元素深度校验开发

Python中的Walrus运算符分析示例详解

《Python中的Walrus运算符分析示例详解》Python中的Walrus运算符(:=)是Python3.8引入的一个新特性,允许在表达式中同时赋值和返回值,它的核心作用是减少重复计算,提升代码简... 目录1. 在循环中避免重复计算2. 在条件判断中同时赋值变量3. 在列表推导式或字典推导式中简化逻辑

Java Stream流使用案例深入详解

《JavaStream流使用案例深入详解》:本文主要介绍JavaStream流使用案例详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录前言1. Lambda1.1 语法1.2 没参数只有一条语句或者多条语句1.3 一个参数只有一条语句或者多

SpringBoot整合mybatisPlus实现批量插入并获取ID详解

《SpringBoot整合mybatisPlus实现批量插入并获取ID详解》这篇文章主要为大家详细介绍了SpringBoot如何整合mybatisPlus实现批量插入并获取ID,文中的示例代码讲解详细... 目录【1】saveBATch(一万条数据总耗时:2478ms)【2】集合方式foreach(一万条数

Python装饰器之类装饰器详解

《Python装饰器之类装饰器详解》本文将详细介绍Python中类装饰器的概念、使用方法以及应用场景,并通过一个综合详细的例子展示如何使用类装饰器,希望对大家有所帮助,如有错误或未考虑完全的地方,望不... 目录1. 引言2. 装饰器的基本概念2.1. 函数装饰器复习2.2 类装饰器的定义和使用3. 类装饰

MySQL 中的 JSON 查询案例详解

《MySQL中的JSON查询案例详解》:本文主要介绍MySQL的JSON查询的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录mysql 的 jsON 路径格式基本结构路径组件详解特殊语法元素实际示例简单路径复杂路径简写操作符注意MySQL 的 J

Python ZIP文件操作技巧详解

《PythonZIP文件操作技巧详解》在数据处理和系统开发中,ZIP文件操作是开发者必须掌握的核心技能,Python标准库提供的zipfile模块以简洁的API和跨平台特性,成为处理ZIP文件的首选... 目录一、ZIP文件操作基础三板斧1.1 创建压缩包1.2 解压操作1.3 文件遍历与信息获取二、进阶技