首页 > 数据库 >Oracle中的sql hint

Oracle中的sql hint

时间:2024-03-07 16:01:33浏览次数:41  
标签:BSEMPMS NO 提示 hint 索引 sql Oracle 优化 id

Hint是Oracle数据库提供的一种机制用来告诉优化器按照hint告诉它的方式生成执行计划,是sql优化中常用的一个手段。

基于代价的优化器,在绝大多数情况下会选择正确的优化器。但是有时候会选择效率很差的执行计划,使某个语句变得很慢,此时就需要通过hint告诉优化器使用指定的存取路径或者连接类型生成执行计划,从而使语句高效地运行。

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

hint提示只能出现在4个关键字后面;
“+”号表示此注释是一个提示,必须紧跟“/*”,且中间不能有空格;
如果包含多个提示,则每个提示之间需要用一个或多个空格隔开;
text是其他说明hint的注释性文本。
hint中的语法错误不会报错,如果解析器不能解析,就会把它看做一个普通的注释处理。

  1. 优化器相关的

OPT_PARAM:作用是使某条语句中指定某个系统参数值;
SELECT /*+ OPT_PARAM('_optimizer_unnest_disjunctive_subq' 'FALSE') */ ... FROM ...

ALL_ROWS:实现查询语句整体最优化而引导优化器制定最少成本的执行计划。优化器会选择一条可最快检索所有查询行的路径,代价就是检索一行时,速度会很慢。
SELECT /*+ALL+_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT';

FIRST_ROWS:为获得最佳响应时间而引导优化器制定最少成本的执行计划。这个提示会使优化器选择可最快检索出查询的第一行(或指定行)数据的路径
SELECT /*+FIRST_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT';

CHOOSE:依据SQL中所使用到的表的统计信息存在与否,来决定使用RBO还是CBO。
SELECT /*+CHOOSE*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT';

RULE:使用基于规则的优化器来实现最优化执行,即引导优化器根据优先顺序规则来决定查询条件中所使用到的索引或运算符的执行 顺序来制定执行计划。
SELECT /*+ RULE */ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT';

  1. 和访问路径相关的

FULL:告诉优化器通过全表扫描方式访问数据。
SELECT /*+FULL(A)*/ EMP_NO,EMP_NAM FROM BSEMPMS A WHERE EMP_NO='SCOTT';

CLUSTER:引导优化器通过扫描聚簇索引来从索引表中读取数据。
SELECT /*+CLUSTER */ BSEMPMS.EMP_NO,DPT_NO FROM BSEMPMS,BSDPTMS   WHERE DPT_NO='TEC304' AND BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;

HASH:引导优化器按照哈希扫描的方式从表中读取数据。

INDEX:告诉优化器对指定表通过索引的方式访问数据。当访问数据会导致结果集不完整时,优化器将忽略这个Hint。
SELECT /*+INDEX(BSEMPMS SEX_INDEX) USE SEX_INDEX BECAUSE THERE ARE FEWMALE BSEMPMS */ FROM BSEMPMS WHERE SEX='M';

NO_INDEX:告诉优化器对指定表不允许使用索引。这个提示会禁止优化器使用指定索引。
select /*+ no_index(emp ind_emp_sal ind_emp_deptno)*/ * from emp where deptno=200 and sal>300;

INDEX_ASC:利用索引从表中读取数据时,引导优化器对提示中所指定索引的索引列值按照升序使用范围扫描。
SELECT /*+INDEX_ASC(BSEMPMS PK_BSEMPMS) */ FROM BSEMPMS WHERE DPT_NO='SCOTT';

INDEX_COMBINE:告诉优化器强制选择位图索引。这个提示会使优化器合并表上的多个位图索引,而不是选择其中最好的索引(这是INDEX提示的用途)。还可以使用index_combine指定单个索引(对于指定位图索引,该提示优先于INDEX提示)。对于B树索引,可以使用AND_EQUAL提示而不是这个提示。
SELECT /*+INDEX_COMBINE(BSEMPMS SAL_BMI HIREDATE_BMI)*/ * FROM BSEMPMS   WHERE SAL<5000000 AND HIREDATE

INDEX_JOIN:索引关联,当谓词中引用的列上都有索引的时候,可以通过索引关联的方式来访问数据。这个提示可以将同一个表的各个不同索引进行合并,这样就只需要访问这些索引就可以了,节省了回表查询的时间。但只能在基于代价的优化器中使用该提示。这个提示不仅允许只访问表上的索引, 这样可以扫描更少的代码块,并且它
比使用索引并通过rowid扫描整个表快5倍。
SELECT /*+INDEX_JOIN(BSEMPMS SAL_HMI HIREDATE_BMI)*/ SAL,HIREDATE   FROM BSEMPMS WHERE SAL<60000;

INDEX_DESC:利用索引从表中读取数据时,引导优化器对提示中所指定索引的索引列值按照降序使用范围扫描。
SELECT /*+INDEX_DESC(BSEMPMS PK_BSEMPMS) */ FROM BSEMPMS WHERE DPT_NO='SCOTT';

INDEX_FFS:告诉优化器以INDEX FFS(index fast full scan)的方式访问数据。INDEX_FFS提示会执行一次索引的快速全局扫描。这个提示只访问索引,而不是对应的表。只有查询需要检索的信息都在索引上时,才使用这个提示。特别在表有很多列时,使用该提示可以极大地改善性能。
SELECT /*+INDEX_FFS(BSEMPMS IN_EMPNAM)*/ * FROM BSEMPMS WHERE DPT_NO='TEC305';

INDEX_SS:强制使用index skip scan的方式访问索引。当在一个联合索引中,某些谓词条件并不在联合索引的第一列时(或者谓词并不在联合索引的第一列时), 可以通过index skip scan来访问索引获得数据。当联合索引第一列的唯一值很少时,使用这种方式比全表扫描的方式效率要高。
select/*+ inde_ss(a idx_1) */ *from tmp_t0 a,tmp_t1 b where 1=1 and a.id=b.id;
3. 和查询转换相关的

USE_CONCAT:将含有多个OR或者IN运算符所连接起来的查询语句分解l为多个单一查询语句,并为每个单一查询语句选择最优化查询路径,然后再将这些最优化查询路径结合在一起,以实现整体查询语句的最优化目的。只有在驱动查询条件中包含OR的时候,才可以使用该提示。
SELECT /*+USE_CONCAT*/ * FROM BSEMPMS WHERE DPT_NO='TDC506' AND SEX='M';

NO_EXPAND:引导优化器不要为使用OR运算符号(或IN运算符)的条件制定相互结合的执行计划。正好和USE_CONCAT相反。
SELECT /*+NO_EXPAND*/ * FROM BSEMPMS WHERE DPT_NO='TDC506' AND SEX='M';

REWRITE:当表连接的对象是数据量比较大的表或者需要获得使用统计函数处理过的结果时,为了提高执行速度可预先创建物化视图。当用户要求查询某个查询语句时,优化器会在从表中和从物化视图中读取数据的两种方法中选择一个更有效的方法来读取数据。该执行方法称之为查询重写。使用REWRITE提示引导优化器按照该方式执行。
select/*+ rewrite */ * from tmp_t0 a,tmp_t1 b where 1=1and a.id=b.id

MERGE:为了能以最优方式从视图或者嵌套视图中读取数据,通过变换查询语句来直接读取视图使用的基表数据,该过程被称之为视图合并。

SELECT /*+MERGE(V) */ A.EMP_NO,A.EMP_NAM,B.DPT_NO FROM BSEMPMS A (SELET DPT_NO   ,AVG(SAL) AS AVG_SAL FROM BSEMPMS B GROUP BY DPT_NO) V WHERE A.DPT_NO=V.DPT_NO   AND A.SAL>V.AVG_SAL;

UNNEST:提示优化器将子查询转换为连接的方式。也就是引导优化器合并子查询和主查询并且将其向连接类型转换。
select a.id from tmp_t0 a where 1=1 and exists (select/*+ unnest */ 1 from tmp_t1 b where 1=1 and a.id=b.id );

NO_UNNEST:引导优化器让子查询能够独立地执行完毕之后再跟外围的查询做FILTER。
select a.id from tmp_t0 a where 1=1 and a.id in (select/*+ no_unnest */ b.id from tmp_t1 b);

PUSH_PRED:谓词推入 ,当SQL语句中包含不能合并的视图,同时视图有谓词过滤,CBO会将谓词过滤条件推入视图中。其目的就是让优化器尽早可能地过滤掉无用的数据,从而提升查询性能。
谓词推入的前提是要有不能合并的视图。
select/*+ push_pred(a) */* from v_tmp_t0_data a,tmp_t1 b where 1=1 and a.id= b.id and b.id=2;

NO_PUSH_PRED:使用该提示确保视图或嵌套视图以外的查询条件不被推入到视图内部。
select /*+ no_push_pred(emp_view_union) */emp.empno from emp,emp_view_union where emp.empno=emp_view_union.empno1 and emp.ename="FORD";

PUSH_SUBQ:使用该提示引导优化器为不能合并的子查询制定执行计划。

select /*+ push_subq(@tmp) */ rownum
        t.*,
        pm.id
        pm.in_price****
        c.justin_cat__name,
        pm.justin_pro_id
   from justin_pro t
   left join justin_cat c
     on c.id = t.justin_cat_id
   join justin_pro_mer pm
     on pm.justin_pro_id = t.id
    and pm.id = (select /*+QB_Name(tmp)*/ id
                   from justin_pro_mer p_m
                  where p_m.justin_pro_id = t.id
                    and p_m.CAN_SALE = :a
                    and rownum = :b)
  where t.is_deleted = :c
    and rownum <= :d
    and t.justin_pro_type <> :e
    and t.is_hot = :f;

NO_PUSH_SUBQ:使用该提示将引导优化器将不能实现合并的子查询放在最后执行。

  1. 和表连接顺序相关的

LEADING:在一个多表关联的查询中,这个Hint指定由哪个表作为驱动表,即告诉优化器首先要访问那个表上的数据。
select/*+ use_nl(a,b) leading(a) */ * from tmp_t0 a,tmp_t1 b where 1=1 and a.id=b.id;

ORDERED:引导优化器按照FROM中所描述的表的顺序执行连接。如果和LEADING提示被一起使用,则LEADING提示将被忽略。
select/*+ ordered */ * from tmp_t0 a,tmp_t1 b where 1=1 and a.id=b.id;

  1. 和表连接操作相关的

USE_NL:使用该提示引导优化器按照嵌套循环连接方式执行表连接。它只是指出表连接的方式,对于表连接顺序不会有任何影响。
SELECT /*+ORDERED USE_NL(BSEMPMS)*/ BSDPTMS.DPT_NO,BSEMPMS.EMP_NO,BSEMPMS.EMP_NAM FROM BSEMPMS,BSDPTMS WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;

USE_MERGE:引导优化器按照排序合并连接方式执行连接。在有必要的情况下,推荐将该提示与ORDERED提示一起使用。提示通常用于获得查询的最佳吞吐量。假设将两个表连接在一起,从每个表返回的行集将被排序,然后再被合并(也就是合并排序),从而组成最终的结果集。由于每个行先被排序之后才进行合并,所以在给定查询中检索所有行时,速度将会最快。如果需要以最快速度返回第一行,就应该使用USE_NL提示。
select /*+ use_merge(t,t1) */ t.* from t,t1 where t.id=t1.id;

USE_HASH:该提示引导优化器按照哈希连接方式执行连接。在执行哈希连接时,如果由于某一边的表比较小,从而可以在内存中实现哈希连接,那么就能够获得非常好的执行速度。
select /*+ use_hash(t,t1) leading(t,t1) */ t.* from t,t1 where t.id=t1.id;

  1. 和并行相关的

PARALLEL:指定SQL执行的并行度,这个值将会覆盖表自身设定的并行度。如果这个值为default,CBO使用系统参数。从表中读取大量数据和执行DML操作时使用该提示来指定SQL的并行操作。一般情况下需要在该提示中指定将要使用的并行线程个数。如果在该提示中没有指定并行度的个数,则优化器将使用PARALLEL_THREADS_PER_CPU 参数所指定的值进行自动计算。如果在定义表时指定了PARALLEL,那么在能够使用并行操作的情况下,即使没有使用该提示,优化器也会按照指定的并行级别选择并行操作。 但是如果想在DELETE、INSERT、UPDATE、MERGE等DML操作中使用并行操作,则必须要在会话中设置ALTER SESSION ENABLE PARALLEL DML。在某个会话中所设置 的并行级别也可以被引用在内部的GROUP BY或者排序操作中。在并行操作中如果出现了某个限制要素,则该提示将被忽略。
select /*+ parallel(emp,4)*/ * from emp where deptno=200 and sal>300;

NOPARALLEL/NO_PARALLEL:在SQL语句禁止使用并行。在有些版本中用NO_PARALLEL提示来代替NOPARALLEL提示。
select /*+ no_parallel(t) */ count(*) from t;

PQ_DISTRIBUTE:为了提高并行连接的执行速度,使用该提示来定义使用何种方法在主从进程之间(例如生产者进程和消费者进程)分配各连接表的数据行。

PARALLEL_INDEX:为了按照并行操作的方式对分区索引进行索引范围扫描而使用该提示,并且可以指定进程的个数。
select /*+ parallel_index(t_parallel,idx_t_parallel,2) */a from t_parallel where a=1;

  1. 其他相关的

APPEND:让数据库以直接加载的方式(direct load)将数据加载入库。这个提示不会检查当前是否有插入所需要的块空间,相反它会直接将数据添加到新块中。这样会浪费空间,但可以提高插入的性能。需要注意的是,数据将被存储在HWM之上的位置。
insert into t /*+ append */ select * from t;

APPEND_VALUES:在11.2中,Oracle新增了APPEND_VALUES提示,使得INSERT INTO VALUES语句也可以使用直接路径插入。
INSERT /*+ APPEND_VALUES(A) */ INTO T_APPEND A VALUES (3, 'APPEND_VALUE');

CACHE:在全表扫描之后,数据块将留在LRU列表的最活跃端。如果设置表的CACHE属性,它的作用和HINT一样。这个提示会将全表扫描全部缓存到内存中。如果表很大,会占用大量内存。因此适用于用户经常访问的较小的表。
SELECT /*+FULL(BSEMPMS) CAHE(BSEMPMS) */ EMP_NAM FROM BSEMPMS;

NOCACHE:引导优化器将通过全表扫描方式获取的数据块缓存在LRU列表的最后位置,这样可以让数据库实例缓存中的这些数据块被优先清除。这是优化器在Buffer Cache中管理数据块的默认方法(仅针对全表扫描)。
SELECT /*+FULL(BSEMPMS) NOCAHE(BSEMPMS) */ EMP_NAM FROM BSEMPMS;

QB_NAME:使用该提示为查询语句块命名,在其他查询语句块可以直接使用该查询语句块的名称。

SELECT /*+ QB_NAME(outer) */
            e.ename
     ,      e.sal
     FROM (
            SELECT /*+ QB_NAME(inline_view) */
                   *
            FROM   emp e
            WHERE e.sal > 300
            AND    e.deptno IN ( SELECT /*+ QB_NAME(dept_subquery) */ d.deptno
                                 FROM   dept d
                                 WHERE d.dname IN (‘SALES’,'ACCOUNTING’) )
           ) e;

DRIVING_SITE:这个提示在分布式数据库操作中有用。指定表是处理连接所在的位置。可以限制通过网络处理的信息量。此外,还可以建立远程表的本地视图来限制从远程站点检索的行。本地视图应该有where子句,从而视图可以在将行发送回本地数据库之前限制从远程数据库返回的行。
SELECT /*+DRIVING_SITE(DEPT)*/ * FROM BSEMPMS,DEPT@BSDPTMS WHERE BSEMPMS.DPT_NO=DEPT.DPT_NO;

DYNAMIC_SAMPLING:提示SQL执行时动态采样的级别。这个级别为0~10,它将覆盖系统默认的动态采样级别。等级越高,所获得统计信息的准确率越高。该提示的功能就是为了确保将动态采样原理应用在单个SQL中。
select /*+ dynamic_sampling(t 4) */ * from t where id > 1234

AND_EQUAL:这个提示会使优化器合并表上的多个索引,而不是选择其中最好的索引(这是INDEX提示的用途)。这个提示与前面的INDEX_JOIN提示有区别,以此指定的合并索引随后需访问表,而INDEX_JOIN提示则只需访问索引。如果发现需经常用到这个提示,可能需要删除这些单个索引而改用一个组合索引。需要查询条件里面包括所有索引列,然后取得每个索引中得到的rowid列表。然后对这些对象做merge join,过滤出相同的rowid后再去表中获取数据或者直接从索引中获得数据。在10g中,and_equal已经废弃了,只能通过hint才能生效。
select/*+ and_equal(a idx_1 idx_2) */ * from tmp_t0 a,tmp_t1 b where 1=1 and a.id=b.id and a.id=2 and a.name='Tom';

CARDINALITY:向优化器提供对某个查询语句的整体或部分的预测基数值,并通过参考该基数值来为查询语句制定执行计划。如果在该提示中没有指定表的名称,则该基数值将被视为从该查询语句所获得的最终结果行数。
select /*+ cardinality(b 100000) */ a.object_name,a.object_type from a,b where a.object_id=b.object_id and b.object_id=1000;

具体来这看
https://docs.oracle.com/cd/B28359_01/server.111/b28274/hintsref.htm#PFGRF501

标签:BSEMPMS,NO,提示,hint,索引,sql,Oracle,优化,id
From: https://www.cnblogs.com/BlackAndBrown/p/18059097

相关文章

  • 使用VS Code 连线MySQL使用
    使用vscode操作mysql,要添加dll1.使用vscode创建MVC项目,在*****.csproj文件里添加ItemGroup点击查看代码<ProjectSdk="Microsoft.NET.Sdk.Web"><PropertyGroup><TargetFramework>net5.0</TargetFramework></PropertyGroup><Item......
  • sqlite.dll介绍,sqlite.dll文件缺失的解决方法,3分钟快速修复sqlite.dll
    第一次见到这个dll,一般是找到这个dll,重新引用下。网上找到了关于这个dll的详细解释,其他dll应该也可以用这些方法修复,在此记录下。原文链接:https://zhuanlan.zhihu.com/p/668219472一.什么是SQLite.dllSQLite.dll是SQLite数据库引擎的一个关键组成部分。(SQLite是一个开源的嵌......
  • 记录一个使用mysql查询表单,多个参数.
    publicDataTableQueryData(SearchViewModelmodel){DataTabledt=newDataTable();/把'删除掉,在编写文档时,不加个',MySqlParameter显示不出来/List<'MySqlParameter>param=newList<'MySqlParameter>();model.inputMonths=model.inputMonth......
  • mysql测试环境和生产环境在同一台服务器上数据迁移避坑
    mysql测试环境和生产环境在同一台服务器上数据迁移要注意:生产库dacs ,测试库dacs_test 1、从生产导出数据:mysqldump-uroot-p --databases dacs >/tmp/dacs.sql如果此时无脑导入就会把生产覆盖了。source /tmp/dacs.sql ;因为t阿玛2、将导出数据的库替......
  • Python中怎么使用Spark的spark.read.format()函数读取MySQL数据库中的数据
    1.准备工作:安装pyspark库(pipinstallpyspark)2.代码:#导入模块frompyspark.sqlimportSparkSession#创建Spark会话对象spark=SparkSession.builder\.appName("ReadMySQL")\.getOrCreate()#或者写成一行spark=SparkSession.builder.appName("ReadMySQL&qu......
  • sqlserver和mysql区别
    1.数据库管理系统SQLServer是由微软公司开发的关系型数据库管理系统,适用于Windows操作系统。而MySQL则是由瑞典MySQL公司开发的,后来被Oracle公司收购,适用于多个操作系统,包括Windows、Linux和UNIX。2.许可证和成本SQLServer是商业产品,需要购买许可证才能使用。它的价格相对......
  • POSTGRESQL (PG) 6种索引类型介绍以及使用实例
    Postgresql中主要支持6种类型的索引:BTREE、HASH、GiST、SP-GiSP、GIN、BRIN。可以根据实际的应用场景选择合适的索引,BTREE、HASH是比较常用的索引。1.BTREE索引:CREATEINDEX默认使用BTREE索引,适合按照顺序存储的数据进行比较查询和范围查询,查询优化器会优先考虑使用BTREE索引,如......
  • Mysql和Oracle自定义函数区别
    1.Mysql自定义函数dropfunctionifexistsget_date;createfunctionget_date(v_datetimedatetime,v_timevarchar(50))returnsvarchar(50)begin declarev_datevarchar(50); declarecDatevarchar(50); declarebeginDatevarchar(50); setcDate=date_format(......
  • MySQL explain
    简介mysqlexplain(或desc)用于分析SQL语句的执行计划,多用于测试查询性能。语法:explainsql...注意explain执行DML语句,数据不发生变化。explain执行的结果可以有多条数据,一条数据对应一个表,如果涉及union,MySQL内部会产生一个临时表,就会导致结果多一行数据。unionall不会创建......
  • 开源.NET8.0小项目伪微服务框架(分布式、EFCore、Redis、RabbitMQ、Mysql等)
    1、前言为什么说是伪微服务框架,常见微服务框架可能还包括服务容错、服务间的通信、服务追踪和监控、服务注册和发现等等,而我这里为了在使用中的更简单,将很多东西进行了简化或者省略了。年前到现在在开发一个新的小项目,刚好项目最初的很多功能是比较通用的,所以就想着将这些功能抽......