优化器提示

提示(Hint)概念

一般在优化时,无论采用基于规则的或是基于代价的方法,由Oracle 系统的优化器来决定语

句的执行路径。这样的选择的路径不要见得是最好的。所以,Oracle 提供了一种方法叫提示的

方法。它可以让编程人员按照自己的要求来选择执行路径,即提示优化器该按照什么样的执

行规则来执行当前的语句。这样可以在性能上比起Oracle 优化自主决定要好些。

通常情况下,编程人员可以利用提示来进行优化决策。通过运用提示可以对下面内容进行指

定:

 SQL 语句的优化方法;

 对于某条SQL 语句,基于开销优化程序的目标;

 SQL 语句访问的访问路径;

 连接语句的连接次序;

 连接语句中的连接操作

提示的指定

如果希望优化器按照编程人员的要求执行,则要在语句中给出提示。提示的有效范围有

限制,即有提示的语句块才能按照提示要求执行。下面语句可以指定提示:

 简单的SELECT ,UPDATE ,DELETE 语句;

 复合的主语句或子查询语句;

 组成查询(UNION)的一部分。

提示的指定有原来的注释语句在加“+”构成。语法如下:

[ SELECT | DELETE|UPDATE ] /*+ [hint | text ] */

[ SELECT | DELETE|UPDATE ] --+ [hint | text ]

注意在“/*”后不要空就直接加“+”,同样 “--+”也是连着写。

警告:如果该提示语句书写不正确,则 Oracle 就忽略掉该语句。

指定完整的提示:

对于复杂的语句,要用/*+ */来指定,它可以指定多个提示语句。且可以换行。

SELECT /*+ ORDERED INDEX (b, jl_br_balances_n1) USE_NL (j b)

USE_NL (glcc glf) USE_MERGE (gp gsb) */

b.application_id ,

b.set_of_books_id ,

b.personnel_id,

p.vendor_id Personnel,

p.segment1 PersonnelNumber,

p.vendor_name Name

FROM jl_br_journals j,

jl_br_balances b,

gl_code_combinations glcc,

fnd_flex_values_vl glf,

gl_periods gp,

gl_sets_of_books gsb,

po_vendors p

WHERE . . . . . . . . . . . .

提示的指定

使用提示,用户可以在基于开销的优化方法和基于规则的优化方法之间选择,由此可以

对要求“最佳吞吐量”与“最佳响应时间”优化目标进行选择。优化方法如下:

 ALL_ROWS

 FIRST_ROWS

 CHOOSE

 RULE

如果某条语句已经指定了优化方法和优化目标后,则Oracle 的优化器就按照指定的优化方法

和目标进行执行。并且不考虑:

1) 是否存在统计信息;

2) 初始化参数OPTIMIZER_MODE 的取值;

3) ALTER SESSION 语句中OPTIMIZER_MODE 参数值。

ALL_ROWS

ALL_ROWS 表示对语句块选择基于开销的优化方法,并且获得最佳的吞吐量(资源消耗

总量最小)作为目标进行优化。语法如下:

/*+ ALL_ROWS */

例子:在查询EMP 表希望用基于开销的优化方法,并获得最佳吞吐量,则使用下面语句:

SELECT /*+ ALL_ROWS */empno,ename,sal,job

FROM emp WHERE empno=7566;

FIRST_ROWS

FIRST_ROWS 表示对语句块选择基于开销的优化方法,并且获得最佳的响应(返回首行

的资源最小化)作为目标进行优化。

使用FIRST_ROWS 优化方法,优化器可能要进行下面工作:

 如果能利用索引扫描,则不进行全表扫描;

 当关联表是嵌套循环的内部表且能用索引扫描,则优化器先优化嵌套循环联结。

 如果通过order by 使得索引扫描可用,则优化器选择索引扫描以避免排序操作。

语法如下:

/*+ FIRST_ROWS */

例子:选择基于开销的优化方法,并希望获得最佳的响应时间,则:

SELECT /*+ FIRST_ROWS */empno,ename,sal,job

FROM emp

WHERE empno=7566;

CHOOSE

选择CHOOSE 表示告诉优化器要在基于开销和基于规则之间进行选择。优化器的确定要

建立在是否存在访问表的统计信息之上:

 如果数据字典中存在该表的统计数据,则选择基于开销,并以最佳吞吐量作为目标。

 如果数据字典中不存在该表的统计数据,则选择基于规则。

语法为:

/*+ CHOOSE */

例子:

SELECT /*+ CHOOSE */ empno,sal,job FROM emp WHERE empno=7566;

RULE

表示要求优化器对语句块选择基于规则的优化方法。语法如下:

/*+ RULE */

例子:

SELECT --+ RULE empno,ename,sal,job

FROM emp WHERE empno=7655;

SELECT /*+ RULE */ empno,ename,sal,job

FROM emp WHERE empno=7655;

访问方法共有:

 FULL

 ROWID

 CLUSTER

 HASH

 INDEX

 INDEX_ASC

 INDEX_COMBINE

 INDEX_JOIN

 INDEX_DESC

 INDEX_FFS

 NO_INDEX

 AND_EQUAL

 USE_CONCAT

 NO_EXPAND

 REWRITE

 NOREWRITE

如果在语句中指定了上面的提示,并且语句所涉及的索引或簇是可用时,优化器就使用所指

定的访问路径。否则,优化器就忽略提示的要求。

FULL

FULL 提示表示对表选择全表扫描的访问方法。语法如下:

/*+ FULL ( [table_name]| [table_aliase] ) */

例:

SELECT /*+ FULL(A) don’t use the index on accno */ accno,bal

FROM accounts a

WHERE accno=7789;

虽然这里使用了带索引的条件句,优化器也得选择全表扫描。

ROWID

ROWID 表示对指定表选择根据rowid 进行表扫描,语法如下:

/*+ ROWID( table_name ) */

例:

SELECT /*+ROWID(emp)*/ * FROM emp

WHERE rowid>’AAAATKAABAAAFNTAAA’ AND empno=155;

CLUSTER

CLUSTER 表示对指定表选择簇扫描的访问方法。它仅对CLUSTER 对象有效。语法如

下:

/*+CLUSTER(table_name) */

例:

SELECT --+CLUSTER emp.ename, deptno

FROM emp,dept

WHERE deptno=10 AND emp.deptno=dept.deptno;

HASH

HASH 表示对指定的表选择HASH 扫描访问方法,它只对CLUSTER 中的表有效。语法

如下:

/*+HASH(table_name)*/

INDEX

INDEX 表示对指定表选择索引扫描的访问方法。用户可以对域、B*树和位图索引应用本

提示。对于建立了位图的索引,建议用INDEX_COMBINE 更为合适。语法如下:

/*+INDEX(table_name [index]) */

例:

SELECT /*+INDEX(patients sex_index)use sex_index because there are few male patients*/

Name,height,weight FROM patients WHERE sex=’m’;

INDEX_ASC

INDEX_ASC 表示对指定的表选择索引的访问方法,并按照升序进行扫描。语法如下:

/*+INDEX_ASC(table_name [index])*/

INDEX_COMBINE

INDEX_COMBINE 表示对指定的表选择位图访问路径。

 如果没有提供可参考的索引,则优化器以最低开销为目标,选择位图索引的布尔组合

方式;

 如果有可参考的索引,则优化器就使用该位图的某写布尔组合。

语法如下:

/*+INDEX_COMBINE(table_name[index])*/

例:

SELECT /*+INDEX_COMBINE(emp sal_bmi hiredate_bmi)*/*

FROM emp

WHERE sal<5000 AND hiredate ,’01-JAN-1990’;

INDEX_JOIN

INDEX_JOIN 表示使用索引连接作为访问路径。语法如下:

/*+INDEX_JOIN(table_name[index])*/

例:

SELECT /*+INDEX_JOIN(emp sal_bmi hiredate_bmi)*/sal,hirdate

FROM emp

WHERE sal<5000 ;

INDEX_DESC

INDEX_DESC 表示对指定表选择索引访问方法。如果使用索引区域扫描,则按照降序进

行扫描。语法如下:

/*+INDEX_DESC(table_name[index])*/

INDEX_FFS

INDEX_DESC 表示对指定表选择快速索引访问方法(不是全表扫描)。语法如下:

/*+INDEX_FFS(table_name[index])*/

例:

SELECT /*+INDEX_FFS(emp emp_empnp)*/ empno

FROM emp

WHERE empno>200;

NO_INDEX

NO_INDEX 表示对指定表禁止选择索引访问方法。语法如下:

/*+NO_INDEX(table_name[index])*/

例:

SELECT /*+NO_INDEX(emp emp_empnp)*/ empno

FROM emp

WHERE empno>200;

AND_EQUAL

AND-EQUAL 表示要进行执行规则的选择。使几个列的索引的扫描合并起来。语法如

下:

/*+AND_EQUAL(table_name[index] [inex]…)*/

USE_CONCAT

USE_CONCAT 提示强制对查询语句中的WHERE 从句的OR 条件进行转换,转化成由

UNION_ALL 集合操作符连接的组合查询。一般来说,如果采用连接查询比不用连接查询低,

则转换为用连接查询。

/*+USE_COMCAT*/

例:

SELECT /*USE_CONCAT*/* FROM emp

WHERE empno>50 OR sal<50000;

NO_EXPAND

NO_EXPAND 对于具有OR 或IN 查询语句,它将阻止基于开销的优化器对其进行OR 扩

展。语法如下:

/*+NO_EXPAND*/

例:

SELECT /*+NO_EXPAND*/*

FROM emp

WHERE empno=50 OR empno=100;

REWRITE

REWRITE 表示可以将视图列表作为参数来看,如果用户使用REWRITE,并且该列表包

含有符合条件的实体化视图,则Oracle 优化器将利用该视图而不用基于开销的方法。而对于

列表以外的视图将不被考虑。如果在REWRITE 中没有给出视图列表,则Oracle 将搜索符合

条件的实体化视图。并且利用该视图。语法如下:

/*+REWRITE(view,[view]…)*/

NOWRITE

NOWRITE 表示禁止对查询块的查询重写操作, 从而避免参数

QUERY_REWRITE_ENABLE 的设置。语法如下:

/*+NOWRITE*/

关于连接次序的提示

ORDERED

根据出现在FROM 中顺序,ORDERED 提示将使得Oracle 依此次序对其进行连接。语法

如下:

/*+ORDERED*/

例:

SELECT /*+ORDERED*/tab1.col1,tabl2.col2,tab3.col3

FROM tab1,tab2,tab3

WHERE tab1.col1=tab2.col1 AND tab2.col1=tab3.col1;

STAR

强行让优化器使用星型查询规划。星型规划拥有查询中最大的一个表,该表位于连接次

序的最后,并与嵌套式循环连接的级联索引连接。如果满足下面3个条件:

1)至少存在3个表;

2)最大表的级联索引至少存在3列;

3)不存在冲突的访问或连接访问提示。

/*+ STAR */

时间: 2024-12-22 21:32:33

优化器提示的相关文章

ORACLE优化器RBO与CBO介绍总结

RBO和CBO的基本概念   Oracle数据库中的优化器又叫查询优化器(Query Optimizer).它是SQL分析和执行的优化工具,它负责生成.制定SQL的执行计划.Oracle的优化器有两种,基于规则的优化器(RBO)与基于代价的优化器(CBO)          RBO: Rule-Based Optimization 基于规则的优化器          CBO: Cost-Based Optimization 基于代价的优化器 RBO 自ORACLE 6以来被采用,一直沿用至ORA

Oracle Optimizer:迁移到使用基于成本的优化器-----系列1.1

oracle|优化 Oracle Optimizer:迁移到使用基于成本的优化器-----系列1.1        如果在Oracle以前的版本(7.0或更早)中开发应用程序,数据库会采用基于规则的优化器(译者注:以下称RBO),本篇将帮助你理解Oracle优化器并迁移到基于成本优化器(译者注:以下称CBO)的几种高效方法.下面是五大部分的第一部分   第一部分 1.         什么是优化器? 2.         为什么要优化? 3.         可用的优化器. 4.        

Oracle Optimizer:迁移到使用基于成本的优化器-----系列1.2

oracle|优化 Oracle Optimizer:迁移到使用基于成本的优化器-----系列1.2 3.2基于成本的优化器(CBO) 基于成本优化器遵循计算代价的方法学.所有的执行计划随成本标识,优化器选择成本最低的一个.在执行计划中,较高的成本将意味着较高的资源.成本越低,对查询来说越高效.CBO使用所有存储在数据字典中可用的统计资料信息和柱状图,用户提供提示和的参数设置来达成使用的成本,CBO生成所有可能访问方法的排列然后选择最合适的.排列的数量依赖于查询中出现的表数量,有时能达到约80,

Oracle Optimizer:迁移到使用基于成本的优化器-----系列1.3

oracle|优化 Oracle Optimizer:迁移到使用基于成本的优化器-----系列1.3   3.2.3     可用CBO模式 CBO有两种运行模式:ALL_ROWS和FIRST_ROWS. FIRST_ROWS的目标是尽可能最快的返回行.这种模式告诉优化器响应时间是最重要的.它偏好嵌套连接方式. FIRST_ROWS也以考虑成本为主要规则来处理行.通常规则是使用索引的计划而不是使用全表扫描的计划作为访问路径,ORDER BY子句导致索引访问,等等 从9i版本起,在First提示中

Oracle Optimizer:迁移到使用基于成本的优化器-----系列1.4

oracle|优化 Oracle Optimizer:迁移到使用基于成本的优化器-----系列1.4 3.2.3最低要求     用CBO的最低要求是设置优化器模式为FRIST_ROWS或者ALL_ROWS(或CHOOSE)并为对象生成统计资料.然而,这并不能保证你的系统能工作到最佳状态.参照第二部分(初始化参数)涉及初始化参数的信息.     不管是否设置优化器模式.如果有以下情况之一,CBO将会自动调用:      1.用到提示.     2.用到分区表.     3.设置并行表 3.2.4

使用智能优化器提高Oracle的性能极限

oracle|性能|优化  使用智能优化器提高Oracle的性能极限       消耗在准备新的SQL语句的时间是Oracle SQL语句执行时间的最重要的组成部分.但是通过理解Oracle内部产生执行计划的机制,你能够控制Oracle花费在评估连接顺序的时间数量,并且能在大体上提高查询性能.准备执行SQL语句       当SQL语句进入Oracle的库缓存后,在该语句准备执行之前,将执行下列步骤: 1)        语法检查:检查SQL语句拼写是否正确和词序. 2)        语义分析

如何用智能优化器提高Oracle的性能

消耗在准备新的SQL语句的时间是Oracle SQL语句执行时间的最重要的组成部分.但是通过理解Oracle 内部产生执行计划的机制,你能够控制Oracle花费在评估连接顺序的时间数量,并且能在大体上提高查询 性能. 准备执行SQL语句 当SQL语句进入Oracle的库缓存后,在该语句准备执行之前,将执行下列步骤: 1) 语法检查:检查SQL语句拼写是否正确和词序. 2) 语义分析:核实所有的与数据字典不一致的表和列的名字. 3) 轮廓存储检查:检查数据字典,以确定该SQL语句的轮廓是否已经存在

Oracle优化器CBO的知识点

ORACLE 提供了基于成本(CostBased)和基于规则(RuleBased)两种优化器,简称为CBO和RBO,用于确定查询操作的执行计划. 一.如何使用CostBased优化器优化查询操作? 如何使用CBO,那么首先要理解这些概念 1.CBO的成本计算的依据 (1)统计信息:与SQL语句所引用的对象相关以及主机的CPU和IO (2)SQL语句本身 (3).环境:例如与优化器相关的参数设置 2.优化器目标:optimizer_mode (1)ALL_ROWS (2)FIRST_ROWS_N

Oracle 12C优化器的巨大变化,上生产必读(上)

序言 优化器是Oracle数据库最吸引人的部件之一,因为它对每一个SQL语句的处理都必不可少.优化器为每个SQL语句确定最有效的执行计划,这是基于给定的查询的结构,可用的关于底层对象的统计信息,以及所有与优化器和执行相关的特性. 随着每个新版本的发布,优化器都会进化,利用新功能以及新的统计信息来生成更好的执行计划.随着对查询优化的新的自适应方法的引入,Oracle 12c数据库把这种进化更推上了一个台阶. 这份白皮书介绍了在Oracle 12c数据库中与优化器和统计相关的所有新特性并且提供了简单