【Oracle篇】使用Hint对优化器的执行计划进行干预(含单表、多表、查询块、声明四大类Hint干预)
💫《博主介绍》:✨又是一天没白过,我是奈斯,从事IT领域✨
💫《擅长领域》:✌️擅长阿里云AnalyticDB for MySQL(分布式数据仓库)、Oracle、MySQL、Linux、prometheus监控;并对SQLserver、NoSQL(MongoDB)有了解✌️
💖💖💖大佬们都喜欢静静的看文章,并且也会默默的点赞收藏加关注💖💖💖

今天这篇文章分享一下《使用Hint对优化器的执行计划进行干预》。首先需要明白为什么需要人工干预SQL语句的执行计划,不是Oracle的优化器会根据统计信息对每个SQL语句执行最优的执行计划的吗?干哈还需要人工来指定执行计划呢?那么我先给出答案: 在大多数情况优化器是会给出最优的执行计划,但并不是所有的情况 。
比如现在有这么一个场景,假设有两张业务表, orders 和 customers ,并且它们通过 customer_id 列关联。我们需要查询所有来自特定城市(例如“New York”)的客户订单数据。Oracle优化器通常会根据统计信息来选择最优的执行计划,可能会选择通过 orders 表进行全表扫描,甚至可能选择一个不那么高效的连接顺序。此时,我们可以使用 LEADING Hint 来干预优化器,让它首先选择 customers 表,然后再进行连接操作,通过指定 /*+ LEADING(customers) */ 告诉优化器优先选择 customers 表来作为驱动表,而不是默认可能的 orders 表。这样做的好处是,当 customers 表的数据量较小,而 orders 表的数据量较大时,优化器通过首先选择小表 customers 来驱动连接,让查询按照我们期望的顺序执行,可以避免在大表上做不必要的扫描,从而提高查询效率。这只是众多需要hint干预的一种情况,还有很多其他情况,那么带着这些问题,开始今天的内容。
特别说明💥:本篇文章部分知识点均来源于 Oracle 公开可查的官方文档手册,并结合了我个人的理解和案例演示。如有冲突,请联系,会立即处理。转载请标明出处😄
官方文档对Hint的详细介绍(Oracle 12c):Influencing the Optimizer
目录
一、使用Hint对优化器的执行计划进行干预
Hint的优点:
Hint的缺点:
Hint的范围:
Hint写法:
联接顺序Hint准则:
1、Hint干预的类型
1.1 单表:单表Hint是在一个表或视图上指定
1.1.1 FULL Hint
1.1.2 INDEX Hint
1.1.3 INDEX_ASC Hint
1.1.4 INDEX_DESC Hint
1.1.5 INDEX_FFS Hint
1.1.6 INDEX_JOIN Hint
1.1.7 INDEX_SS Hint
1.1.8 INDEX_SS_ASC Hint
1.1.9 INDEX_SS_DESC Hint
1.2 多表:多表Hint类似于单表Hint,只是该Hint可以指定多个表或视图
1.2.1 LEADING Hint
1.2.2 MERGE Hint
1.2.3 USE_BAND Hint
1.2.4 USE_CONCAT Hint
1.2.5 USE_CUBE Hint
1.2.6 USE_HASH Hint
1.2.7 USE_MERGE Hint
1.2.8 USE_NL Hint
1.2.9 USE_NL_WITH_INDEX Hint
1.3 查询块:查询块Hint对单个查询块进行操作
1.3.1 STAR_TRANSFORMATION Hint
1.3.2 UNNEST Hint
1.4 声明:声明Hint适用于整个SQL语句
1.4.1 ALL_ROWS Hint
1.4.2 FIRST_ROWS Hint
干预优化器执行计划的几种技术方式:
Oracle提供了多种干预执行计划的技术,包括DBMS_STATS、SQL profiles、SQL Plan Management、参数(优化器相关),和最后的hint方式。下图是博主手绘了一张关于干预优化器执行计划的五种方式:
技术 描述 参数(优化器相关) 参数在数据库实例和会话级别影响许多类型的优化器行为。 Hints Hint是SQL语句中的特殊注释,它将指令传递给优化器。Hint 的主要作用是向优化器提供指示,按照用户预先定义的计划来执行 SQL 语句的执行计划。
DBMS_STATS 官方文档中将DBMS_STATS包定义为了干预优化器执行计划的技术。但是严格意义上来说DBMS_STATS只是用来收集统计信息的包,统计信息越精准,优化器选择的执行计划就越优,但并不能通过DBMS_STATS包指定想要的执行计划,因为DBMS_STATS收集完成统计信息之后,优化器会根据统计信息对每个SQL语句执行最优的执行计划,这个过程是Oracle优化器完成的,人工并没有参与。
SQL profiles Oracle绑定执行计划有两种方式:SQL Profile和SQL Plan Management (SPM)。其中对于Oracle 10g 及之前的版本,一般采用SQL Profile来绑定执行计划,而对于Oracle 11g以后的版本,一般采用SPM来实现自动化的执行计划管理。
SQL plan management 干预优化器执行计划的五种技术方式今天只介绍Hints方式。 关于参数(优化器相关)这种方式因为在大多数情况下参数都是最优的所以一般不需要进行调整;关于SQL profiles、SQL plan management和DBMS_STATS这三种方式因为文章篇幅的原因这篇文章就不做介绍了哦,因为这三种方式涉及到的内容非常多,需要专门写对应的博客😁
需要干预优化器执行计划的几种情况:
在Oracle数据库中,基于代价的优化器(Cost-Based Optimizer,CBO)通常能够自动选择最优的执行计划来执行SQL语句。然而,在某些特定情况下,优化器可能无法选择出最优的执行计划(在大多数情况优化器是会给出最优的执行计划,但并不是所有的情况),这时就需要干预优化器的执行计划。以下是需要进行干预的几种典型情况:
- 优化器选择不当的执行计划:有时优化器可能因为统计信息不准确、物理结构不合理(如缺少合适的索引)或数据分布的变化等原因,选择了不理想的执行计划,导致SQL语句执行效率低下。此时,DBA可以通过hint来指定存取路径或连接类型,引导优化器生成更优的执行计划。
- 特定场景下的优化需求:在某些特定场景下,如需要快速返回查询结果的前几行(而不是全部结果),或者当全表扫描比索引扫描更有效时,DBA可以通过hint来指定优化器的优化目标或访问路径,以满足特定的业务需求。
- 数据结构和数据规模发生重大变化:当数据结构或数据规模发生重大变化时,原有的执行计划可能不再适用。此时,DBA可以通过hint来指示优化器使用新的存取路径或连接类型,以适应变化后的数据环境。
- 避免复杂的提示和保持执行计划稳定性:在某些情况下,仅通过转换优化器的模式就可以获得非常好的执行计划,此时无需额外使用复杂的hint。然而,在某些复杂查询中,为了确保优化器产生最优的执行计划,可能需要指定全套的hint,包括存取路径、连接类型、连接顺序等。同时,为了避免执行计划的不稳定,DBA也需要在必要时使用hint来固定执行计划。
- 应对特殊表或索引的访问需求:对于某些特殊的表或索引,如聚簇索引或分区表,DBA可能需要通过hint来指示优化器按照特定的方式访问数据,以提高查询性能。
需要注意的是,Hint 是用来约束优化器行为的一种技术,用来辅助DBA和研发人员用来做性能排查和优化,过多的干预可能会导致执行计划不稳定,甚至恶化查询性能,因此尽量避免在开发中使用。毕竟数据是不断变化的,大多数情况下应该让Oracle自行决定采用什么样的执行计划。
一、使用Hint对优化器的执行计划进行干预
使用Hint来影响优化器模式(optimizer mode)、查询转换(query transformation)、访问路径(access path)、连接顺序(join order)和连接方法(join methods)。
当发现一条 SQL 执行效率较低(即执行时间较长)时,首先需要查看该 SQL 的执行计划。如果分析后发现执行计划不够优化,就需要调查 CBO 为什么选择了不合适的执行计划。通过使用 hint 来修改执行计划,并比较两种执行计划的效率,从而确定最优方案。此外,若 CBO 选择了错误的执行计划,还应检查表的统计信息是否最新,是否对相关列创建了直方图,是否对分区表进行了全局或分区级别的统计分析等。
总结:Hint 的主要作用是向优化器提供指示,按照用户预先定义的计划来执行 SQL 语句的执行计划。
Hint的优点:
在测试环境中,Hint对于测试特定访问路径的性能非常有用。例如:小伙伴们可能知道走索引对某些查询更具选择性,在这种情况下,使用Hint会让优化器生成更好的执行计划,如下图所示:
Hint的缺点:
Oracle 7中引入了Hint,由于Hint是人工定义的计划,所以这部分是额外的部分,也就是每次执行SQL时都要写上就比较麻烦,Oracle官网给的好办法就是使用Hint进行测试,如果使用Hint的执行计划提高了SQL效率,然后通过使用其他技术来管理执行计划。Oracle提供了几个SQL优化工具用于替代Hint,并且Oracle官网强烈建议使用这些工具而不是Hint,包括SQL调优顾问(SQL Tuning Advisor)、SQL计划管理(SQL plan management)和SQL性能分析器(SQL Performance Analyzer),以解决优化器无法解决的性能问题。
Hint的范围:
在语句块中指定Hint时,该Hint将应用于相应的查询块、表或语句块中的整个语句。Hint会覆盖任何实例级或会话级参数。
Hint支持的语句有:
1. MERGE、SELECT、INSERT、UPDATE、DELETE语句中
2. 父语句或者子查询中
3. 集合查询中(UNION、MINUS、INTERSECT)
Hint写法:
Hint注释必须紧跟在SQL语句块的第一个关键字之后。可以使用两种注释样式:斜线星号(/*)或一对破折号(--)。加号(+)提示分隔符必须紧跟在注释分隔符之后,如以下片段所示:
SELECT /*+ hint_text */ ...一个语句中只能有一个包含Hint的注释,但它可以包含许多空格分隔的Hint。例如,一个复杂的查询可能包括多个表连接。如果只为指定的表指定INDEX提示,则优化器必须确定剩余的访问路径和相应的连接方法。优化器可能不会使用INDEX提示,因为连接方法和访问路径会阻止它。下图使用多个Hint来指定确切的连接顺序。
SELECT /*+ LEADING(e2 e1) USE_NL(e1) INDEX(e1 emp_emp_id_pk) USE_MERGE(j) FULL(j) */e1.first_name, e1.last_name, j.job_id, sum(e2.salary) total_sal FROM employees e1, employees e2, job_history j WHERE e1.employee_id = e2.manager_id AND e1.employee_id = j.employee_id AND e1.hire_date = j.start_date GROUP BY e1.first_name, e1.last_name, j.job_id ORDER BY total_sal;小提示:如果Hint的写法有问题,Oracle也不会提示错误哦(这点真鸡肋。。。),Oracle会直接忽略掉写法有问题的Hint。
联接顺序Hint准则:
在某些情况下,可以在SQL语句中指定联接顺序提示,这样它就不会访问对结果没有影响的行。
联接中的驱动表是与其他表联接的表。一般来说,驱动表包含过滤条件,该条件消除了表中最高百分比的行。连接顺序对SQL语句的性能有很大的影响。
考虑以下准则:
- 当索引更有效地检索请求的行时,避免全表扫描。
- 当可以使用获取少量行的不同索引时,请避免使用从驱动表中获取许多行的索引。
- 选择联接顺序,以便在联接顺序的后面将较少的行联接到表中。
以下示例显示了如何有效地调整连接顺序:
SELECT * FROM taba a, tabb b, tabc c WHERE a.acol BETWEEN 100 AND 200 AND b.bcol BETWEEN 10000 AND 20000 AND c.ccol BETWEEN 10000 AND 20000 AND a.key1 = b.key1 AND a.key2 = c.key2;
- 选择驱动表和驱动索引(如果有):上例中的前三个条件都是应用于单个表的筛选条件。最后两个条件是连接条件。筛选条件决定了驱动表和索引的选择。一般来说,驱动表包含过滤条件,可消除最高百分比的行。因为100到200的范围相对于acol的范围来说比较窄,但是10000和20000的范围比较大,taba就是驾驶台,其他都一样。对于嵌套循环连接,连接通过连接索引进行,连接索引是主键或外键上的索引,用于将该表连接到连接树中较早的表。除了驱动表,很少在非连接条件下使用索引。因此,在选择taba作为驱动表之后,使用b.key1和c.key2上的索引分别驱动到tabb和tabc中。
- 选择最佳连接顺序,最早使用最佳未用过滤器:通过首先连接到具有最好的仍未使用的过滤器的表,可以减少后续连接的工作量。因此,如果bcol BETWEEN比ccol BETWEEN更严格(拒绝更高百分比的行),那么如果在tabc之前联接tabb,最后的联接会变得更容易(具有更少的行)。
- 可以使用ORDERED或STAR提示来强制联接顺序。
1、Hint干预的类型
Hint可以对四种类型进行干预,分别可以对单表(Single-table)、多表(Multitable)、查询块(query blocks)、声明(statements)使用Hint。并且Oracle提供了快100个Hint干预,这篇文章也不可能介绍所有,只是把我认为重要的Hint给介绍,其他需要学习的可以参考官网文档哦,敬上 Hint 官网链接:Comments
1.1 单表:单表Hint是在一个表或视图上指定
1.1.1 FULL Hint
使用语法:
/*+ FULL ( [ @ queryblock ] tablespec ) */
介绍:
FULL Hint提示优化器对指定表执行全表扫描。例如:
SELECT /*+ FULL(e) */ employee_id, last_nameFROM hr.employees e WHERE last_name LIKE :b1;数据库对employees表执行全表扫描以执行此语句,即使WHERE子句中的条件使last_name列上有索引。
employees表在FROM子句中有别名e,因此Hint必须通过别名而不是引用该表。即使在FROM子句中指定了表名,但也不要在Hint中指定它们。
1.1.2 INDEX Hint
使用语法:
/*+ INDEX ( [ @ queryblock ] tablespec [ indexspec [ indexspec ]... ] ) */
介绍:
INDEX Hint指示优化器对指定表使用索引扫描。您可以将INDEX提示用于基于函数的索引、域索引、B树索引、位图索引和位图连接索引。
- 如果index Hint指定了一个可用的索引,那么数据库将对该索引执行扫描。优化器不会考虑全表扫描或表上另一个索引的扫描。
- 对于多个索引组合的提示,Oracle建议使用INDEX_COMBINE而不是INDEX,因为它是一个更通用的提示。如果INDEX提示指定了可用索引的列表,则优化器会考虑列表中每个索引的扫描成本,然后以最低成本执行索引扫描。如果这种访问路径的成本最低,数据库还可以选择扫描此列表中的多个索引并合并结果。数据库不考虑全表扫描或对提示中未列出的索引的扫描。
- 如果INDEX提示未指定索引,则优化器会考虑对表上每个可用索引的扫描成本,然后以最低成本执行索引扫描。如果这种访问路径的成本最低,数据库还可以选择扫描多个索引并合并结果。优化器不考虑全表扫描。
INDEX Hint示例:
SELECT /*+ INDEX (employees emp_department_ix)*/ employee_id, department_idFROM employees WHERE department_id > 50;
1.1.3 INDEX_ASC Hint
使用语法:
/*+ INDEX_ASC ( [ @ queryblock ] tablespec [ indexspec [ indexspec ]... ] ) */
介绍:
INDEX_ASC提示指示优化器对指定表使用索引扫描。如果语句使用索引范围扫描,则Oracle数据库会按索引值的升序扫描索引条目。每个参数的作用与INDEX Hint中的相同。
范围扫描的默认行为是按索引值的升序扫描索引条目,或按降序扫描索引条目。此提示不会更改索引的默认顺序,因此仅指定index提示。但是,如果默认行为发生变化,您可以使用INDEX_ASC提示显式指定升序范围扫描。
1.1.4 INDEX_DESC Hint
使用语法:
/*+ INDEX_DESC ( [ @ queryblock ] tablespec [ indexspec [ indexspec ]... ] ) */
介绍:
INDEX_DESC提示指示优化器对指定表使用降序索引扫描。如果语句使用索引范围扫描,并且索引是升序的,则Oracle会按索引值的降序扫描索引条目。在分区索引中,结果在每个分区内按降序排列。对于降序索引,此提示有效地取消了降序,导致按升序扫描索引条目。每个参数的作用与INDEX提示中的相同。例如:
SELECT /*+ INDEX_DESC(e emp_name_ix) */ *FROM employees e;
1.1.5 INDEX_FFS Hint
使用语法:
/*+ INDEX_FFS ( [ @ queryblock ] tablespec [ indexspec [ indexspec ]... ] ) */
介绍:
INDEX_FFS Hint指示优化器执行索引快速全扫描(Index Fast Full Scans),而不是全表扫描。每个参数的作用与INDEX提示中的相同。例如:
SELECT /*+ INDEX_FFS(e emp_name_ix) */ first_nameFROM employees e;
1.1.6 INDEX_JOIN Hint
使用语法:
/*+ INDEX_JOIN ( [ @ queryblock ] tablespec [ indexspec [ indexspec ]... ] ) */
介绍:
INDEX_JOIN Hint指示优化器使用索引联接作为访问路径。为了使提示产生积极的效果,必须存在足够少的索引,其中包含解析查询所需的所有列。
每个参数的作用与INDEX Hint中的相同。例如,以下查询使用索引联接来访问manager_id和department_id列,这两列都在employees表中索引。
SELECT /*+ INDEX_JOIN(e emp_manager_ix emp_department_ix) */ department_idFROM employees eWHERE manager_id < 110AND department_id < 50;
1.1.7 INDEX_SS Hint
使用语法:
/*+ INDEX_SS ( [ @ queryblock ] tablespec [ indexspec [ indexspec ]... ] ) */
介绍:
INDEX_SS Hint指示优化器对指定表执行索引跳跃扫描(Index Skip Scans)。如果语句使用索引范围扫描,则Oracle会按索引值的升序扫描索引条目。在分区索引中,结果在每个分区内按升序排列。
每个参数的作用与INDEX Hint中的相同。例如:
SELECT /*+ INDEX_SS(e emp_name_ix) */ last_nameFROM employees eWHERE first_name = 'Steven';
1.1.8 INDEX_SS_ASC Hint
使用语法:
/*+ INDEX_SS_ASC ( [ @ queryblock ] tablespec [ indexspec [ indexspec ]... ] ) */
介绍:
INDEX_SS_ASC提示指示优化器对指定的表执行索引跳过扫描。如果语句使用索引范围扫描,那么Oracle数据库将按照索引值的升序扫描索引条目。在分区索引中,结果在每个分区中按升序排列。每个参数的作用与INDEX Hint中的相同。
范围扫描的默认行为是按照索引值的升序扫描索引项,或者按照降序扫描降序索引项。该提示不会更改索引的默认顺序,因此除了INDEX_SS提示之外,不会指定任何其他内容。但是,如果默认行为发生变化,可以使用INDEX_SS_ASC提示显式指定升序范围扫描。
1.1.9 INDEX_SS_DESC Hint
使用语法:
/*+ INDEX_SS_DESC ( [ @ queryblock ] tablespec [ indexspec [ indexspec ]... ] ) */
介绍:
INDEX_SS_DESC提示指示优化器对指定的表执行索引跳过扫描。如果语句使用索引范围扫描,并且索引是升序的,那么Oracle将按照索引值的降序扫描索引条目。在分区索引中,结果在每个分区中按降序排列。对于降序索引,该提示有效地取消了降序,从而以升序扫描索引条目。
每个参数的作用与index Hint中的相同。例如:
SELECT /*+ INDEX_SS_DESC(e emp_name_ix) */ last_nameFROM employees eWHERE first_name = 'Steven';
1.2 多表:多表Hint类似于单表Hint,只是该Hint可以指定多个表或视图
1.2.1 LEADING Hint
使用语法:
/*+ LEADING ( [ @ queryblock ] tablespec [ tablespec ]... ) */
介绍:
LEADING提示指示优化器使用指定的一组表作为执行计划中的前缀。这个提示比有序提示更通用。例如:
SELECT /*+ LEADING(e j) */ *FROM employees e, departments d, job_history jWHERE e.department_id = d.department_idAND e.hire_date = j.start_date;如果指定的表由于连接图中的依赖关系而无法按指定的顺序首先连接,则忽略LEADING Hint。如果指定了两个或更多冲突的LEADING Hint,则所有这些提示都将被忽略。如果指定ORDERED提示,它将覆盖所有LEADING Hint。
1.2.2 MERGE Hint
使用语法:
/*+ MERGE [ ( @ queryblock ) | ( [ @ queryblock ] tablespec ) ] */
介绍:
MERGE提示允许合并查询中的视图。
如果视图的查询块在选择列表中包含GROUP BY子句或DISTINCT运算符,则只有在启用了复杂视图合并时,优化器才能将视图合并到访问语句中。如果子查询不相关,也可以使用复杂合并将IN子查询合并到访问语句中。示例:
SELECT /*+ MERGE(v) */ e1.last_name, e1.salary, v.avg_salaryFROM employees e1,(SELECT department_id, avg(salary) avg_salary FROM employees e2GROUP BY department_id) v WHERE e1.department_id = v.department_idAND e1.salary > v.avg_salaryORDER BY e1.last_name;使用不带参数的MERGE提示时,应该将其放在视图查询块中。当MERGE与作为参数的视图名称一起使用时,它应该放在周围的查询中。
1.2.3 USE_BAND Hint
使用语法:
/*+ USE_BAND ( [ @ queryblock ] tablespec [ tablespec ]... ) */
介绍:
USE_BAND提示指示优化器使用带连接将每个指定的表与另一个行源连接起来。例如:
SELECT /*+ USE_BAND(e1 e2) */e1.last_name|| ' has salary between 100 less and 100 more than '|| e2.last_name AS "SALARY COMPARISON" FROM employees e1, employees e2 WHERE e1.salary BETWEEN e2.salary - 100 AND e2.salary + 100;
1.2.4 USE_CONCAT Hint
使用语法:
/*+ USE_CONCAT [ ( @ queryblock ) ] */
介绍:
USE_CONCAT提示指示优化器使用UNION ALL集合运算符将查询的WHERE子句中的组合OR条件转换为复合查询。如果没有这个提示,只有当使用连接的查询成本比不使用连接的成本低时,才会发生这种转换。USE_CONCAT提示覆盖了成本考虑。例如:
SELECT /*+ USE_CONCAT */ *FROM employees eWHERE manager_id = 108OR department_id = 110;
1.2.5 USE_CUBE Hint
使用语法:
/*+ USE_CUBE ( [ @ queryblock ] tablespec [ tablespec ]... ) */
介绍:
当联接的右侧是一个多维数据集时,USE_CUBE提示指示优化器使用多维数据集联接将每个指定的表与另一个行源联接起来。如果优化器基于统计分析决定不使用多维数据集连接,那么您可以使用USE_CUBE来覆盖该决定。
1.2.6 USE_HASH Hint
使用语法:
/*+ USE_HASH ( [ @ queryblock ] tablespec [ tablespec ]... ) */
介绍:
USE_HASH提示指示优化器使用散列连接将每个指定的表与另一个行源连接起来。例如:
SELECT /*+ USE_HASH(l h) */ *FROM orders h, order_items lWHERE l.order_id = h.order_idAND l.order_id > 2400;
1.2.7 USE_MERGE Hint
使用语法:
/*+ USE_MERGE ( [ @ queryblock ] tablespec [ tablespec ]... ) */
介绍:
USE_MERGE提示指示优化器使用排序合并联接将每个指定的表与另一个行源联接起来。例如:
SELECT /*+ USE_MERGE(employees departments) */ * FROM employees, departments WHERE employees.department_id = departments.department_id;建议将USE_NL和USE_MERGE提示与LEADING和ORDERED提示一起使用。当被引用的表被强制作为连接的内部表时,优化器使用这些提示。如果被引用的表是外部表,则忽略提示。
1.2.8 USE_NL Hint
使用语法:
/*+ USE_NL ( [ @ queryblock ] tablespec [ tablespec ]... ) */
介绍:
USE_NL提示指示优化器使用指定的表作为内部表,通过嵌套循环联接将每个指定的表联接到另一个行源。
USE_NL提示指示优化器使用指定的表作为内部表,通过嵌套循环联接将每个指定的表联接到另一个行源。
建议将USE_NL和USE_MERGE提示与LEADING和ORDERED提示一起使用。当被引用的表被强制作为连接的内部表时,优化器使用这些提示。如果被引用的表是外部表,则忽略提示。
在下面的示例中,通过提示强制执行嵌套循环,通过全表扫描访问orders,并将筛选条件l.order_id = h.order_id应用于每一行。对于满足筛选条件的每一行,order_items通过索引order_id进行访问。
SELECT /*+ USE_NL(l h) */ h.customer_id, l.unit_price * l.quantityFROM orders h, order_items lWHERE l.order_id = h.order_id;向查询中添加索引提示可以避免对订单进行全表扫描,从而产生一个类似于大型系统中使用的执行计划,尽管它在这里可能不是特别有效。
1.2.9 USE_NL_WITH_INDEX Hint
使用语法:
/*+ USE_NL_WITH_INDEX ( [ @ queryblock ] tablespec [ indexspec [ indexspec ]... ] ) */
介绍:
USE_NL_WITH_INDEX提示指示优化器使用指定的表作为内部表,通过嵌套循环联接将指定的表联接到另一个行源。例如:
SELECT /*+ USE_NL_WITH_INDEX(l item_product_ix) */ *FROM orders h, order_items lWHERE l.order_id = h.order_idAND l.order_id > 2400;以下条件适用:
- 如果没有指定索引,那么优化器必须能够使用至少有一个连接谓词的索引作为索引键。
- 如果指定了索引,那么优化器必须能够将该索引与至少一个连接谓词一起用作索引键。
1.3 查询块:查询块Hint对单个查询块进行操作
1.3.1 STAR_TRANSFORMATION Hint
使用语法:
/*+ STAR_TRANSFORMATION [ ( @ queryblock ) ] */
介绍:
STAR_TRANSFORMATION提示指示优化器使用使用了转换的最佳计划。如果没有提示,优化器可能会做出查询优化决策,使用没有转换时生成的最佳计划,而不是转换后查询的最佳计划。例如:
SELECT /*+ STAR_TRANSFORMATION */ s.time_id, s.prod_id, s.channel_idFROM sales s, times t, products p, channels cWHERE s.time_id = t.time_idAND s.prod_id = p.prod_idAND s.channel_id = c.channel_idAND c.channel_desc = 'Tele Sales';即使指定了提示,也不能保证转换会发生。只有在合理的情况下,优化器才会生成子查询。如果没有生成子查询,则没有已转换的查询,并且使用未转换查询的最佳计划,而不管提示如何。
1.3.2 UNNEST Hint
使用语法:
/*+ UNNEST [ ( @ queryblock ) ] */
介绍:
UNNEST提示指示优化器取消嵌套并将子查询的正文合并到包含它的查询块的正文中,从而允许优化器在评估访问路径和连接时将它们放在一起考虑。
在取消嵌套子查询之前,优化器首先验证语句是否有效。然后,语句必须通过启发式和查询优化测试。UNNEST提示指示优化器只检查子查询块的有效性。如果子查询块有效,则启用子查询取消嵌套,而不检查试探法或开销。
1.4 声明:声明Hint适用于整个SQL语句
1.4.1 ALL_ROWS Hint
ALL_ROWS提示指示优化器以最佳吞吐量(即最小的总资源消耗)为目标优化语句块。例如,优化器使用查询优化方法来优化此语句,以获得最佳吞吐量:
SELECT /*+ ALL_ROWS */ employee_id, last_name, salary, job_idFROM employeesWHERE employee_id = 107;如果在SQL语句中指定ALL_ROWS或FIRST_ROWS Hint,并且如果数据字典没有关于该语句访问的表的统计信息,则优化器使用默认统计值,例如为这些表分配的存储,来估计缺失的统计信息并随后选择执行计划。这些估计可能不如DBMS_STATS包收集的估计准确,因此应该使用DBMS_STATS包收集统计信息。
如果为访问路径或联接操作指定提示以及ALL_ROWS或FIRST_ROWS提示,则优化器会优先考虑提示指定的访问路径和联接操作。
1.4.2 FIRST_ROWS Hint
FIRST_ROWS提示指示Oracle优化单个SQL语句以获得快速响应,选择最有效地返回前n行的计划。对于整数,指定要返回的行数。
例如,优化器使用查询优化方法来优化以下语句,以获得最佳响应时间:
SELECT /*+ FIRST_ROWS(10) */ employee_id, last_name, salary, job_idFROM employeesWHERE department_id = 20;在本例中,每个部门都包含许多员工。用户希望尽快显示部门20的前10名雇员。
优化器在DELETE和UPDATE语句块以及包含任何阻塞操作(如排序或分组)的SELECT语句块中忽略此提示。此类语句无法优化以获得最佳响应时间,因为Oracle数据库必须在返回第一行之前检索语句访问的所有行。如果在任何此类语句中指定此提示,则数据库将优化以获得最佳吞吐量。
每篇文章我都认真对待,只求质量不求数量,所以博主大概产出一篇文章需要4天到7天,这篇文章从构思到发布用了10天,所以真心不容易,觉得写的好的小伙伴请不吝自己的小手进行一键三连,点赞、收藏、加关注哦👋。
相关文章:
【Oracle篇】使用Hint对优化器的执行计划进行干预(含单表、多表、查询块、声明四大类Hint干预)
💫《博主介绍》:✨又是一天没白过,我是奈斯,从事IT领域✨ 💫《擅长领域》:✌️擅长阿里云AnalyticDB for MySQL(分布式数据仓库)、Oracle、MySQL、Linux、prometheus监控;并对SQLserver、NoSQL(…...
论文阅读(九):通过概率图模型建立连锁不平衡模型和进行关联研究:最新进展访问之旅
1.论文链接:Modeling Linkage Disequilibrium and Performing Association Studies through Probabilistic Graphical Models: a Visiting Tour of Recent Advances 摘要: 本章对概率图模型(PGMs)的最新进展进行了深入的回顾&…...
【信息系统项目管理师-选择真题】2005上半年综合知识答案和详解
更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 【第1题】【第2~3题】【第4~6题】【第7题】【第8题】【第9题】【第10~11题】【第12题】【第13题】【第14题】【第15题】【第16题】【第17题】【第18~19题】【第20题】【第21~22题】【第23题】【第24~25题】【第…...
【Matlab高端绘图SCI绘图模板】第006期 对比绘柱状图 (只需替换数据)
1. 简介 柱状图作为科研论文中常用的实验结果对比图,本文采用了3组实验对比的效果展示图,代码已调试好,只需替换数据即可生成相关柱状图,为科研加分。通过获得Nature配色的柱状图,让你的论文看起来档次更高࿰…...
【Elasticsearch】 Intervals Query
Elasticsearch Intervals Query 返回基于匹配术语的顺序和接近度的文档。 intervals 查询使用 匹配规则,这些规则由一小组定义构建而成。这些规则然后应用于指定 field 中的术语。 这些定义生成覆盖文本中术语的最小间隔序列。这些间隔可以进一步由父源组合和过滤…...
YOLOv8源码修改(4)- 实现YOLOv8模型剪枝(任意YOLO模型的简单剪枝)
目录 前言 1. 需修改的源码文件 1.1添加C2f_v2模块 1.2 修改模型读取方式 1.3 增加 L1 正则约束化训练 1.4 在tensorboard上增加BN层权重和偏置参数分布的可视化 1.5 增加剪枝处理文件 2. 工程目录结构 3. 源码文件修改 3.1 添加C2f_v2模块和模型读取 3.2 添加L1正则…...
数论问题80
命题1,证明,方程(2x)^(2x)-1y^(z1)没有正整数解。 分析:设x,y,z∈Z满足方程,当x1时,3y^(z1),无论任意y,z取任意正整数值,3y^(z1)都不成立。方程左端分解因式,…...
后端token校验流程
获取用户信息 前端中只有 await userStore.getInfo() 表示从后端获取数据 在页面中找到info对应的url地址,在IDEA中查找 这里是getInfo函数的声明,我们要找到这个函数的使用,所以点getInfo() Override public JSONObject getInfo() {JSO…...
Ansible自动化运维实战--通过role远程部署nginx并配置(8/8)
文章目录 1、准备工作2、创建角色结构3、编写任务4、准备配置文件(金甲模板)5、编写变量6、编写处理程序7、编写剧本8、执行剧本Playbook9、验证-游览器访问每台主机的nginx页面 在 Ansible 中,使用角色(Role)来远程部…...
C语言自定义数据类型详解(二)——结构体类型(下)
书接上回,前面我们已经给大家介绍了如何去声明和创建一个结构体,如何初始化结构体变量等这些关于结构体的基础知识。下面我们将继续给大家介绍和结构体有关的知识: 今天的主题是:结构体大小的计算并简单了解一下位段的相关知识。…...
OpenFeign的工作原理是什么?它第一次加载的时候为什么慢?
OpenFeign的工作原理是什么?它第一次加载的时候为什么慢? OpenFeign的工作原理 接口定义: 开发者定义一个接口,并使用 FeignClient 注解指定该接口所对应的微服务名称。在接口的方法上添加 HTTP 方法相关的注解(如 …...
LLM架构与优化:从理论到实践的关键技术
标题:“LLM架构与优化:从理论到实践的关键技术” 文章信息摘要: 文章探讨了大型语言模型(LLM)开发与应用中的关键技术,包括Transformer架构、注意力机制、采样技术、Tokenization等基础理论,以…...
Maven的单元测试
1. 单元测试的基本概念 单元测试(Unit Testing) 是一种软件测试方法,专注于测试程序中的最小可测试单元——通常是单个类或方法。通过单元测试,可以确保每个模块按预期工作,从而提高代码的质量和可靠性。 2.安装和配…...
Jetson Xavier NX 安装 CUDA 支持的 PyTorch 指南
本指南将帮助开发者完成在 Jetson Xavier NX 上安装 CUDA 支持的 PyTorch。 安装方法 在 Jetson 上安装 Pytorch 只有两种方法。 一种是直接安装他人已经编译好的 PyTorch 轮子;一种是自己从头开始开始构建 PyTorch 轮子并且安装。 使用轮子安装 可以从我的 Gi…...
AI协助探索AI新构型的自动化创新概念
训练AI自生成输出模块化代码,生成元代码级别的AI功能单元代码,然后再由AI组织为另一个AI,实现AI开发AI的能力;用AI协助探索迭代新构型AI将会出现,并成为一种新的技术路线潮流。 有限结点,无限的连接形式&a…...
Kafka 压缩算法详细介绍
文章目录 一 、Kafka 压缩算法概述二、Kafka 压缩的作用2.1 降低网络带宽消耗2.2 提高 Kafka 生产者和消费者吞吐量2.3 减少 Kafka 磁盘存储占用2.4 减少 Kafka Broker 负载2.5 降低跨数据中心同步成本 三、Kafka 压缩的原理3.1 Kafka 压缩的基本原理3.2. Kafka 压缩的工作流程…...
GWO优化GRNN回归预测matlab
灰狼优化算法(Grey Wolf Optimizer,简称 GWO),是一种群智能优化算法,由澳大利亚格里菲斯大学的 Mirjalii 等人于 2014 年提出。该算法的设计灵感源自灰狼群体的捕食行为,核心思想在于模拟灰狼社会的结构与行…...
Unity 粒子特效在UI中使用裁剪效果
1.使用Sprite Mask 首先建立一个粒子特效在UI中显示 新建一个在场景下新建一个空物体,添加Sprite Mask组件,将其的Layer设置为UI相机渲染的UI层, 并将其添加到Canvas子物体中,调整好大小,并选择合适的Spriteÿ…...
【大厂AI实践】OPPO:大规模知识图谱及其在小布助手中的应用
导读:OPPO知识图谱是OPPO数智工程系统小布助手团队主导、多团队协作建设的自研大规模通用知识图谱,目前已达到数亿实体和数十亿三元组的规模,主要落地在小布助手知识问答、电商搜索等场景。 本文主要分享OPPO知识图谱建设过程中算法相关的技…...
C# 添加、替换、提取、或删除Excel中的图片
在Excel中插入与数据相关的图片,能将关键数据或信息以更直观的方式呈现出来,使文档更加美观。此外,对于已有图片,你有事可能需要更新图片以确保信息的准确性,或者将Excel 中的图片单独保存,用于资料归档、备…...
AI大模型开发原理篇-5:循环神经网络RNN
神经概率语言模型NPLM也存在一些明显的不足之处:模型结构简单,窗口大小固定,缺乏长距离依赖捕捉,训练效率低,词汇表固定等。为了解决这些问题,研究人员提出了一些更先进的神经网络语言模型,如循环神经网络、…...
赛博算卦之周易六十四卦JAVA实现:六幺算尽天下事,梅花化解天下苦。
佬们过年好呀~新年第一篇博客让我们来场赛博算命吧! 更多文章:个人主页 系列文章:JAVA专栏 欢迎各位大佬来访哦~互三必回!!! 文章目录 #一、文化背景概述1.文化起源2.起卦步骤 #二、卦象解读#三、just do i…...
iperf 测 TCP 和 UDP 网络吞吐量
注:本文为 “iperf 测网络吞吐量” 相关文章合辑。 未整理去重。 使用 iperf3 监测网络吞吐量 Tom 王 2019-12-21 22:23:52 一 iperf3 介绍 (1.1) iperf3 是一个网络带宽测试工具,iperf3 可以擦拭 TCP 和 UDP 带宽质量。iperf3 可以测量最大 TCP 带宽…...
内外网文件摆渡企业常见应用场景和对应方案
在如今的企业环境中,内外网文件摆渡的需求越来越常见,也变得越来越重要。随着信息化的不断推进,企业内部和外部之间的数据交换越来越频繁,如何安全、高效地进行文件传输成了一个关键问题。今天,咱就来聊聊内外网文件摆…...
【微服务与分布式实践】探索 Sentinel
参数设置 熔断时长 、最小请求数、最大RT ms、比例阈值、异常数 熔断策略 慢调⽤⽐例 当单位统计时⻓内请求数⽬⼤于设置的最⼩请求数⽬,并且慢调⽤的⽐例⼤于阈值,则接下来的熔断时⻓内请求会⾃动被熔断 异常⽐例 当单位统计时⻓内请求数⽬⼤于设置…...
论文阅读(十五):DNA甲基化水平分析的潜变量模型
1.论文链接:Latent Variable Models for Analyzing DNA Methylation 摘要: 脱氧核糖核酸(DNA)甲基化与细胞分化密切相关。例如,已经观察到肿瘤细胞中的DNA甲基化编码关于肿瘤的表型信息。因此,通过研究DNA…...
Android View 的事件分发机制解析
前言:当一个事件发生时(例如触摸屏幕),事件会从根View(通常是Activity的布局中的最顶层View)开始,通过一个特定的路径传递到具体的View,这个过程涉及到三个关键的阶段:事…...
内容检索(2025.01.30)
随着创作数量的增加,博客文章所涉及的内容越来越庞杂,为了更为方便地阅读,后续更新发布的文章将陆续在此汇总并附上原文链接,感兴趣的小伙伴们可持续关注文章发布动态! 博客域名:http://my-signal.blog.cs…...
【25美赛A题-F题全题目解析】2025年美国大学生数学建模竞赛(MCM/ICM)解题思路|完整代码论文集合
我是Tina表姐,毕业于中国人民大学,对数学建模的热爱让我在这一领域深耕多年。我的建模思路已经帮助了百余位学习者和参赛者在数学建模的道路上取得了显著的进步和成就。现在,我将这份宝贵的经验和知识凝练成一份全面的解题思路与代码论文集合…...
新鲜速递:DeepSeek-R1开源大模型本地部署实战—Ollama + MaxKB 搭建RAG检索增强生成应用
在AI技术快速发展的今天,开源大模型的本地化部署正在成为开发者们的热门实践方向。最火的莫过于吊打OpenAI过亿成本的纯国产DeepSeek开源大模型,就在刚刚,凭一己之力让英伟达大跌18%,纳斯达克大跌3.7%,足足是给中国AI产…...



