优化器提示

简介:
提示(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 */

目录
相关文章
|
SQL 存储 算法
PostgreSQL 执行计划,成本公式解说,代价因子校准,自动跟踪SQL执行计划(二)|学习笔记
快速学习PostgreSQL 执行计划,成本公式解说,代价因子校准,自动跟踪SQL执行计划(二)
285 0
PostgreSQL 执行计划,成本公式解说,代价因子校准,自动跟踪SQL执行计划(二)|学习笔记
|
11月前
|
SQL Oracle 关系型数据库
Oracle优化04-Optimizer优化器
Oracle优化04-Optimizer优化器
79 0
|
测试技术
loadrunner 脚本优化-参数化之场景中的参数化取值
loadrunner 脚本优化-参数化之场景中的参数化取值
104 0
|
SQL 移动开发 关系型数据库
PostgreSQL 执行计划,成本公式解说,代价因子校准,自动跟踪SQL执行计划(三)|学习笔记
快速学习PostgreSQL 执行计划,成本公式解说,代价因子校准,自动跟踪SQL执行计划(三)
545 0
PostgreSQL 执行计划,成本公式解说,代价因子校准,自动跟踪SQL执行计划(三)|学习笔记
|
SQL XML JSON
PostgreSQL 执行计划,成本公式解说,代价因子校准,自动跟踪SQL执行计划(一)|学习笔记
快速学习PostgreSQL 执行计划,成本公式解说,代价因子校准,自动跟踪SQL执行计划(一)
484 0
PostgreSQL 执行计划,成本公式解说,代价因子校准,自动跟踪SQL执行计划(一)|学习笔记
|
机器学习/深度学习 存储 PyTorch
pytorch优化器与学习率设置详解
pytorch优化器与学习率设置详解
|
SQL JSON 关系型数据库
几个必须掌握的SQL优化技巧(四):使用Trace工具分析优化器执行计划
在应用的开发过程中,由于开发初期的数据量一般都比较小,所以开发过程中一般都比较注重功能上的实现,但是当完成了一个应用或者系统之后,随着生产数据量的急剧增长,那么之前的很多sql语句的写法就会显现出一定的性能问题,对生产的影响也会越来越大,这些不恰当的sql语句就会成为整个系统性能的瓶颈,为了追求系统的极致性能,必须要对它们进行优化。
352 0
几个必须掌握的SQL优化技巧(四):使用Trace工具分析优化器执行计划
|
SQL Oracle 关系型数据库
数据库查询优化器论文列表
过去一年间,对优化器相关论文做了个系统性的学习,把过程中阅读的论文笔记记录在这里,和大家分享,欢迎大家和我一起讨论,纠错补差,共同进步 ~ 阅读路线基本遵照了pingcap github上的一个Awesome Database Learning的资料,这个资料非常棒,包含了一些基本的课程 + 书籍,还按照内核中不同模块的不同方面做了分类,非常系统化,尤其是SQL层面非常详尽,正好符合需求,因此阅读基本也是按其中的paper来,并扩展到一些没有涉及的内容,总体目录如下(优化器部分),由于内容较多,主要挑选其中影响力较大的或者最有参考意义的。
927 0
|
SQL 数据库
SQL2008 提示评估期已过的解决方法
提示窗口:   解决步骤:   第一步:进入SQL2008配置工具中的安装中心第二步:再进入维护界面,选择版本升级第三步:进入产品密钥,输入密钥第四步:一直点下一步,直到升级完毕。 SQL Server 2008 Developer(开发版):PTTFM-X467G-P7RH2-3Q6CG-4DMYB SQL Server 2008 Enterprise(企业版):JD8Y6-HQG69-P9H84-XDTPG-34MBB注意:如以上选择“版本升级”总提示“失败”并要求“重启计算机”时,请把进程中的Server等服务关闭即可。
1092 0
|
存储 SQL 关系型数据库
MySQL8.0 · 优化器新特性 · Cost Model, 直方图及优化器开销优化
MySQL当前已经发布到MySQL8.0版本,在新的版本中,可以看到MySQL之前被人诟病的优化器部分做了很多的改动,由于笔者之前的工作环境是5.6,最近切换到最新的8.0版本,本文涵盖了一些本人感兴趣的和优化器相关的部分,主要包括MySQL5.7的cost model以及MySQL8.0的直方图功能。
3045 0