Fork me on GitHub
余鸢

Oracle-Hints

Parallel Hint(平行提示)

语句级并行提示是最简单的:

1
SELECT /*+ PARALLEL(8) */ first_name, last_name FROM employee emp;

对象级并行提示提供更多的控制,但更容易出错; 开发人员经常忘记使用别名来代替对象名称,或者他们忘记包含一些对象。

1
SELECT /*+ PARALLEL(emp,8) */ first_name, last_name FROM employee emp;

SELECT /*+ PARALLEL(table_alias,Degree of Parallelism) */ FROM table_name table_alias;

比方说,一个查询需要100秒内没有使用并行提示来执行。 如果我们改变DOP为2相同的查询,则最好用并行提示相同的查询将需要50秒。 同样使用DOP作为4将需要25秒。

在实践中,并行执行取决于许多其他因素,并且不线性缩放。 这对于小的运行时间尤其如此,其中并行开销可能大于在多个并行服务器中运行的增益。

USE_NL

使用嵌套循环。

用法:use_nl(A B)

这个提示会要求引擎使用嵌套循环方法来连接表A和B.这是逐行比较。 提示不强制连接的顺序,只是要求NL。

1
2
3
SELECT /*+use_nl(e d)*/ *
FROM Employees E
JOIN Departments D on E.DepartmentID = D.ID

附录提示

“使用DIRECT PATH方法插入新行”。

APPEND提示指示引擎使用直接路径负载。 这意味着引擎不会使用使用内存结构和标准锁的常规插入,而是将直接写入表空间的数据。 始终创建附加到表的段的新块。 这将更快,但有一些限制:

  • 在你启动或回滚事务之前,你不能从同一会话中附加的表中读取。
  • 如果在表上定义了触发器,Oracle将不会使用直接路径(sqlldr加载的另一个情节)。
  • 其他

例:

1
2
3
INSERT /*+append*/ INTO Employees
SELECT *
FROM Employees;

FULL(充分)

FULL提示告诉Oracle对指定的表执行全表扫描,无论是否可以使用索引。

1
2
create table fullTable(id) as select level from dual connect by level < 100000;
create index idx on fullTable(id);

没有提示,使用索引:

1
2
3
4
5
6
7
8
select count(1) from fullTable f where id between 10 and 100;
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 13 | 3 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 13 | | |
|* 2 | INDEX RANGE SCAN| IDX | 2 | 26 | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------

FULL提示强制进行全面扫描:

1
2
3
4
5
6
7
8
select /*+ full(f) */ count(1) from fullTable f where id between 10 and 100;
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 13 | 47 (3)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 13 | | |
|* 2 | TABLE ACCESS FULL| FULLTABLE | 2 | 26 | 47 (3)| 00:00:01 |
--------------------------------------------------------------------------------

Result Cache(结果缓存)

Oracle(11g及更高版本)允许SQL查询在SGA中缓存,并重用以提高性能。 它从缓存而不是数据库查询数据。 后续执行相同的查询更快,因为现在正从缓存中提取数据。

1
SELECT /*+ result_cache */ number FROM main_table;

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Number
------
1
2
3
4
5
6
7
8
9
10
Elapsed: 00:00:02.20

如果我现在再次运行相同的查询,执行的时间将减少,因为数据现在从缓存获取,在第一次执行期间设置。

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Number
------
1
2
3
4
5
6
7
8
9
10
Elapsed: 00:00:00.10

注意已用时间从2.20秒减少到0.10秒。

结果缓存保存缓存,直到数据库中的数据被更新/更改/删除。 任何更改都将释放缓存。

USE_HASH

指示引擎使用散列法连接参数中的表。

用法:use_hash(TableA [TableB] ... [TableN])

正如许多地方所解释的,“在HASH连接中,Oracle访问一个表(通常是较小的连接结果),并在内存中的连接键上构建一个哈希表,然后扫描连接中的另一个表(通常是较大 一个)并探测哈希表匹配它。

当表很大,没有索引等时,它优先于嵌套循环方法。

注意:提示不强制连接的顺序,只是请求HASH JOIN方法。

使用示例:

1
2
3
SELECT /*+use_hash(e d)*/ *
FROM Employees E
JOIN Departments D on E.DepartmentID = D.ID