当前位置: 首页 > news >正文

【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语句。然而,在某些特定情况下,优化器可能无法选择出最优的执行计划(在大多数情况优化器是会给出最优的执行计划,但并不是所有的情况),这时就需要干预优化器的执行计划。以下是需要进行干预的几种典型情况:

  1. 优化器选择不当的执行计划:有时优化器可能因为统计信息不准确、物理结构不合理(如缺少合适的索引)或数据分布的变化等原因,选择了不理想的执行计划,导致SQL语句执行效率低下。此时,DBA可以通过hint来指定存取路径或连接类型,引导优化器生成更优的执行计划。
  2. 特定场景下的优化需求:在某些特定场景下,如需要快速返回查询结果的前几行(而不是全部结果),或者当全表扫描比索引扫描更有效时,DBA可以通过hint来指定优化器的优化目标或访问路径,以满足特定的业务需求。
  3. 数据结构和数据规模发生重大变化:当数据结构或数据规模发生重大变化时,原有的执行计划可能不再适用。此时,DBA可以通过hint来指示优化器使用新的存取路径或连接类型,以适应变化后的数据环境。
  4. 避免复杂的提示和保持执行计划稳定性:在某些情况下,仅通过转换优化器的模式就可以获得非常好的执行计划,此时无需额外使用复杂的hint。然而,在某些复杂查询中,为了确保优化器产生最优的执行计划,可能需要指定全套的hint,包括存取路径、连接类型、连接顺序等。同时,为了避免执行计划的不稳定,DBA也需要在必要时使用hint来固定执行计划。
  5. 应对特殊表或索引的访问需求:对于某些特殊的表或索引,如聚簇索引或分区表,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语句的性能有很大的影响。

    考虑以下准则:

  1. 当索引更有效地检索请求的行时,避免全表扫描。
  2. 当可以使用获取少量行的不同索引时,请避免使用从驱动表中获取许多行的索引。
  3. 选择联接顺序,以便在联接顺序的后面将较少的行联接到表中。

    以下示例显示了如何有效地调整连接顺序:

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;
  1. 选择驱动表和驱动索引(如果有):上例中的前三个条件都是应用于单个表的筛选条件。最后两个条件是连接条件。筛选条件决定了驱动表和索引的选择。一般来说,驱动表包含过滤条件,可消除最高百分比的行。因为100到200的范围相对于acol的范围来说比较窄,但是10000和20000的范围比较大,taba就是驾驶台,其他都一样。对于嵌套循环连接,连接通过连接索引进行,连接索引是主键或外键上的索引,用于将该表连接到连接树中较早的表。除了驱动表,很少在非连接条件下使用索引。因此,在选择taba作为驱动表之后,使用b.key1和c.key2上的索引分别驱动到tabb和tabc中。
  2. 选择最佳连接顺序,最早使用最佳未用过滤器:通过首先连接到具有最好的仍未使用的过滤器的表,可以减少后续连接的工作量。因此,如果bcol BETWEEN比ccol BETWEEN更严格(拒绝更高百分比的行),那么如果在tabc之前联接tabb,最后的联接会变得更容易(具有更少的行)。
  3. 可以使用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干预)

&#x1f4ab;《博主介绍》&#xff1a;✨又是一天没白过&#xff0c;我是奈斯&#xff0c;从事IT领域✨ &#x1f4ab;《擅长领域》&#xff1a;✌️擅长阿里云AnalyticDB for MySQL(分布式数据仓库)、Oracle、MySQL、Linux、prometheus监控&#xff1b;并对SQLserver、NoSQL(…...

【Rust自学】15.7. 循环引用导致内存泄漏

说句题外话&#xff0c;这篇文章真心很难&#xff0c;有看不懂可以在评论区问&#xff0c;我会尽快作答的。 喜欢的话别忘了点赞、收藏加关注哦&#xff08;加关注即可阅读全文&#xff09;&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω…...

4.scala默认参数值

Scala具备给参数提供默认值的能力&#xff0c;这样调用者就可以忽略这些具有默认值的参数。 def log(message: String, level: String "INFO") println(s"$level: $message")log("System starting") // prints INFO: System starting log(&q…...

前端知识速记—JS篇:null 与 undefined

前端知识速记—JS篇&#xff1a;null 与 undefined 什么是 null 和 undefined&#xff1f; 1. undefined 的含义 undefined 是 JavaScript 中默认的值&#xff0c;表示某个变量已被声明但尚未被赋值。当尝试访问一个未初始化的变量、函数没有返回值时&#xff0c;都会得到 u…...

微信小程序中常见的 跳转方式 及其特点的表格总结(wx.navigateTo 适合需要返回上一页的场景)

文章目录 详细说明总结wx.navigateTo 的特点为什么 wx.navigateTo 最常用&#xff1f;其他跳转方式的使用频率总结 以下是微信小程序中常见的跳转方式及其特点的表格总结&#xff1a; 跳转方式API 方法特点适用场景wx.navigateTowx.navigateTo({ url: 路径 })保留当前页面&…...

【人工智能】基于Python的机器翻译系统,从RNN到Transformer的演进与实现

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 机器翻译(Machine Translation, MT)作为自然语言处理领域的重要应用之一,近年来受到了广泛的关注。在本篇文章中,我们将详细探讨如何使…...

蓝桥备赛指南(5)

queue队列 queue是一种先进先出的数据结构。它提供了一组函数来操作和访问元素&#xff0c;但它的功能相对较简单&#xff0c;queue函数的内部实现了底层容器来存储元素&#xff0c;并且只能通过特定的函数来访问和操作元素。 queue函数的常用函数 1.push()函数&#xff1a;…...

蓝桥云客 好数

0好数 - 蓝桥云课 问题描述 一个整数如果按从低位到高位的顺序&#xff0c;奇数位&#xff08;个位、百位、万位…&#xff09;上的数字是奇数&#xff0c;偶数位&#xff08;十位、千位、十万位…&#xff09;上的数字是偶数&#xff0c;我们就称之为“好数”。 给定一个正…...

CF 764B.Timofey and cubes(Java实现)

题目分析 输入n个数字&#xff0c;首尾交换&#xff0c;奇数对换&#xff0c;偶数对不换 思路分析 存入数组&#xff0c;遍历时判断i%20时(数组下标0开始&#xff0c;所以题目分析没有错)&#xff0c;对换 代码 import java.util.*;public class Main {public static void ma…...

四.3 Redis 五大数据类型/结构的详细说明/详细使用( hash 哈希表数据类型详解和使用)

四.3 Redis 五大数据类型/结构的详细说明/详细使用&#xff08; hash 哈希表数据类型详解和使用&#xff09; 文章目录 四.3 Redis 五大数据类型/结构的详细说明/详细使用&#xff08; hash 哈希表数据类型详解和使用&#xff09;2.hash 哈希表常用指令(详细讲解说明)2.1 hset …...

AIGC(生成式AI)试用 20 -- deepseek 初识

>> 基本概念 Ollama -- 运行大模型&#xff0c;管理运行AI大模型的工具&#xff0c;用来安装布置DeepSeek https://ollama.com/ , Get up and running with large language models. AnythingLLM -- 大模型增强应用&#xff0c;GUI大模型交互程序 Download AnythingLLM …...

你好!这是我自己的CSDN博客!

写于2025年1月30日 我是一个普通的嵌入式软件程序员&#xff0c;喜欢研究Linux&#xff08;应用层跟内核从都有粗浅的涉略&#xff09;&#xff0c;单片机&#xff0c;操作系统和计算机体系架构等内容&#xff0c;目前是一枚普通的本科生。 笔者是一个朴素的开源主义者&#xf…...

将pandas.core.series.Series类型的小数转化成百分数

大年初二&#xff0c;大家过年好&#xff0c;蛇年行大运&#xff01; 今天在编写一个代码的时候&#xff0c;使用 import pandas as pd产生了pandas.core.series.Series类型的数据&#xff0c;里面有小数&#xff0c;样式如下&#xff1a; 目的&#xff1a;将这些小数转化为百…...

[EAI-027] RDT-1B,目前最大的用于机器人双臂操作的机器人基础模型

Paper Card 论文标题&#xff1a;RDT-1B: a Diffusion Foundation Model for Bimanual Manipulation 论文作者&#xff1a;Songming Liu, Lingxuan Wu, Bangguo Li, Hengkai Tan, Huayu Chen, Zhengyi Wang, Ke Xu, Hang Su, Jun Zhu 论文链接&#xff1a;https://arxiv.org/ab…...

oracle中使用in 和 not in 查询效率分析

在Oracle数据库中&#xff0c;IN和NOT IN的查询效率受多种因素影响&#xff0c;以下是关键点总结和优化建议&#xff1a; 1. IN 的效率 优化方式&#xff1a; IN 通常会被优化为 OR条件 或 半连接&#xff08;Semi-Join&#xff09;&#xff0c;如果子查询关联到外部表&#x…...

【python】四帧差法实现运动目标检测

四帧差法是一种运动目标检测技术&#xff0c;它通过比较连续四帧图像之间的差异来检测运动物体。这种方法可以在一定的程度上提高检测的准确性。 目录 1 方案 2 实践 ① 代码 ② 效果图 1 方案 具体的步骤如下&#xff1a; ① 读取视频流&#xff1a;使用cv2.VideoCapture…...

指针的介绍4【回调函数、qsort函数的运用】

1.回调函数 1.1定义 回调函数就是通过函数指针而被调用的函数 把函数的指针&#xff08;地址&#xff09;作为参数传递给另⼀个函数&#xff0c;当这个指针被⽤来调⽤其所指向的函数 时&#xff0c;被调⽤的函数就是回调函数 回调函数不是由该函数的实现⽅直接调⽤&#xff0…...

Attention Free Transformer (AFT)-2020论文笔记

名称&#xff1a; Attention Free Transformer (AFT) 来源&#xff1a; [2105.14103] An Attention Free Transformer 相关工作&#xff1a; #Approximatingthedotproduct #Sparselocalattention #Contextcompression #Eliminatingdotproductattention #MLPsforvision 创…...

Pyside的QWebEngineProfile类

QWebEngineProfile 是 PySide/Qt 中用于管理浏览器引擎&#xff08;WebEngine&#xff09;配置的类&#xff0c;属于 QtWebEngineCore 模块。它主要用于控制网页的全局行为&#xff0c;例如缓存、Cookie、持久化存储、用户代理&#xff08;User-Agent&#xff09;、代理设置等。…...

Java继承中的静态方法隐藏与实例变量隐藏:深入解析与最佳实践

引言 在Java面向对象编程中&#xff0c;继承是实现代码复用的核心机制。然而&#xff0c;继承中的静态方法&#xff08;static&#xff09;和实例变量的行为常常让开发者感到困惑。许多初学者甚至经验丰富的程序员容易混淆方法覆盖&#xff08;Override&#xff09;、方法隐藏…...

day6手机摄影社区,可以去苹果摄影社区学习拍摄技巧

逛自己手机的社区&#xff1a;即&#xff08;手机牌子&#xff09;摄影社区 拍照时防止抖动可以控制自己的呼吸&#xff0c;不要大喘气 拍一张照片后&#xff0c;如何简单的用手机修图&#xff1f; HDR模式就是让高光部分和阴影部分更协调&#xff08;拍风紧时可以打开&…...

从AD的原理图自动提取引脚网络的小工具

这里跟大家分享一个我自己写的小软件&#xff0c;实现从AD的原理图里自动找出网络名称和引脚的对应。存成文本方便后续做表格或是使用简单行列编辑生成引脚约束文件&#xff08;如.XDC .UCF .TCL等&#xff09;。 我们在FPGA设计中需要引脚锁定文件&#xff0c;就是指示TOP层…...

H3CNE-31-BFD

Bidirectional Forwarding Dection&#xff0c;双向转发检查 作用&#xff1a;毫秒级故障检查&#xff0c;通常结合三层协议&#xff08;静态路由、vrrp、ospf、BGP等&#xff09;&#xff0c;实现链路故障快速检查。 BFD配置示例 没有中间的SW&#xff0c;接口down&#xff…...

Linux安装zookeeper

1, 下载 Apache ZooKeeperhttps://zookeeper.apache.org/releases.htmlhttps://zookeeper.apache.org/releases.htmlhttps://zookeeper.apache.org/releases.htmlhttps://zookeeper.apache.org/releases.htmlhttps://zookeeper.apache.org/releases.htmlhttps://zookeeper.apa…...

QPS 值是怎样进行计算和应用的

1. QPS 值的定义 QPS&#xff08;Queries Per Second&#xff09;&#xff0c;即每秒查询率&#xff0c;指一台服务器每秒能够相应 的查询次数&#xff0c;是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。它表示系统在某一特定时间内能够处理的查询请求的数量…...

【视频+图文详解】HTML基础4-html标签的基本使用

图文教程 html标签的基本使用 无序列表 作用&#xff1a;定义一个没有顺序的列表结构 由两个标签组成&#xff1a;<ul>以及<li>&#xff08;两个标签都属于容器级标签&#xff0c;其中ul只能嵌套li标签&#xff0c;但li标签能嵌套任何标签&#xff0c;甚至ul标…...

内外网文件摆渡企业常见应用场景和对应方案

在如今的企业环境中&#xff0c;内外网文件摆渡的需求越来越常见&#xff0c;也变得越来越重要。随着信息化的不断推进&#xff0c;企业内部和外部之间的数据交换越来越频繁&#xff0c;如何安全、高效地进行文件传输成了一个关键问题。今天&#xff0c;咱就来聊聊内外网文件摆…...

基于微信小程序的新闻资讯系统设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…...

透视B/S架构与C/S架构:构建未来网络应用的智慧选择

透视B/S架构与C/S架构&#xff1a;构建未来网络应用的智慧选择 在信息技术迅猛发展的今天&#xff0c;网络架构的选择对企业和开发者来说至关重要。B/S架构&#xff08;Browser/Server&#xff09;与C/S架构&#xff08;Client/Server&#xff09;是两种主流的架构模式&#x…...

受击反馈HitReact、死亡效果Death Dissolve、Floating伤害值Text(末尾附 客户端RPC )

受击反馈HitReact 设置角色受击标签 (GameplayTag基本了解待补充) 角色监听标签并设置移动速度 创建一个受击技能&#xff0c;并应用GE 实现设置角色的受击蒙太奇动画 实现角色受击时播放蒙太奇动画&#xff0c;为了保证通用性&#xff0c;将其设置为一个函数&#xff0c;并…...

【网络】3.HTTP(讲解HTTP协议和写HTTP服务)

目录 1 认识URL1.1 URI的格式 2 HTTP协议2.1 请求报文2.2 响应报文 3 模拟HTTP3.1 Socket.hpp3.2 HttpServer.hpp3.2.1 start()3.2.2 ThreadRun()3.2.3 HandlerHttp&#xff08;&#xff09; 总结 1 认识URL 什么是URI&#xff1f; URI 是 Uniform Resource Identifier的缩写&…...

mysql_init和mysql_real_connect的形象化认识

解析总结 1. mysql_init 的作用 mysql_init 用于初始化一个 MYSQL 结构体&#xff0c;为后续数据库连接和操作做准备。该结构体存储连接配置及状态信息&#xff0c;是 MySQL C API 的核心句柄。 示例&#xff1a; MYSQL *conn mysql_init(NULL); // 初始化连接句柄2. mysql_…...

01.01、判定字符是否唯一

01.01、[简单] 判定字符是否唯一 1、题目描述 实现一个算法&#xff0c;确定一个字符串 s 的所有字符是否全都不同。 在这一题中&#xff0c;我们的任务是判断一个字符串 s 中的所有字符是否全都不同。我们将讨论两种不同的方法来解决这个问题&#xff0c;并详细解释每种方法…...

[NOIP2007]矩阵取数游戏

点我写题 题目描述 帅帅经常跟同学玩一个矩阵取数游戏&#xff1a;对于一个给定的n*m的矩阵&#xff0c;矩阵中的每个元素aij均为非负整数。游戏规则如下&#xff1a; 1.每次取数时须从每行各取走一个元素&#xff0c;共n个。m次后取完矩阵所有元素&#xff1b; 2.每次取走的…...

C++模板初识

文章目录 一、函数模板1. 函数模板2. 函数模板、模板的特例化、非模板函数的重载关系3. 外部调用4. 模板的非类型参数5. 代码示例 二、类模板 一、函数模板 1. 函数模板 模板函数&#xff1a;在函数调用点&#xff0c;编译器用用户指定的类型&#xff0c;从原模板实例化一份函…...

C# Winform制作一个登录系统

using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;namespace 登录 {p…...

Kafka常见问题之 org.apache.kafka.common.errors.RecordTooLargeException

文章目录 Kafka常见问题之 org.apache.kafka.common.errors.RecordTooLargeException: The message is 1,048,576 bytes when serialized which is larger than the maximum request size.1. 错误解析2. 错误原因3. 错误复现案例3.1 生产者发送超大消息 4. 解决方案4.1 方法 1&…...

Python | Pytorch | Tensor知识点总结

如是我闻&#xff1a; Tensor 是我们接触Pytorch了解到的第一个概念&#xff0c;这里是一个关于 PyTorch Tensor 主题的知识点总结&#xff0c;涵盖了 Tensor 的基本概念、创建方式、运算操作、梯度计算和 GPU 加速等内容。 1. Tensor 基本概念 Tensor 是 PyTorch 的核心数据结…...

arm-linux-gnueabihf安装

Linaro Releases windows下打开wsl2中的ubuntu&#xff0c;资源管理器中输入&#xff1a; \\wsl$gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz 复制到/home/ark01/tool 在 Ubuntu 中创建目录&#xff1a; /usr/local/arm&#xff0c;命令如下&#xff1a; …...

C++ 堆栈分配的区别

这两种声明方式有什么区别 1.使用 new 关键字动态分配内存 动态分配&#xff1a;使用 new 关键字会在堆&#xff08;heap&#xff09;上分配内存&#xff0c;并返回一个指向该内存位置的指针。生命周期&#xff1a;对象的生命周期不会随着声明它的作用域结束而结束&#xff0…...

大数据相关职位 职业进阶路径

大数据相关职位 & 职业进阶路径 &#x1f4cc; 大数据相关职位 & 职业进阶路径 大数据领域涵盖多个方向&#xff0c;包括数据工程、数据分析、数据治理、数据科学等&#xff0c;每个方向的进阶路径有所不同。以下是大数据相关职位的详细解析及其职业进阶关系。 &#…...

【计算机网络】设备更换地区后无法访问云服务器问题

文章目录 1. **服务器的公网 IP 是否变了**2. **服务器的防火墙或安全组设置**3. **本地运营商或 NAT 限制**4. **ISP 限制或端口封锁**5. **服务器监听地址检查** 1. 服务器的公网 IP 是否变了 在服务器上运行以下命令&#xff0c;检查当前的公网 IP&#xff1a;curl ifconfi…...

STM32标准库移植RT-Thread nano

STM32标准库移植RT-Thread Nano 哔哩哔哩教程链接&#xff1a;STM32F1标准库移植RT_Thread Nano 移植前的准备 stm32标准库的裸机代码&#xff08;最好带有点灯和串口&#xff09;RT-Thread Nano Pack自己的开发板 移植前的说明 本人是在读学生&#xff0c;正在学习阶段&a…...

【C++题解】1055. 求满足条件的整数个数

欢迎关注本专栏《C从零基础到信奥赛入门级&#xff08;CSP-J&#xff09;》 问题&#xff1a;1055. 求满足条件的整数个数 类型&#xff1a;简单循环 题目描述&#xff1a; 在 1∼n 中&#xff0c;找出能同时满足用 3 除余 2 &#xff0c;用 5 除余 3 &#xff0c;用 7 除余…...

DeepSeek R1-Zero vs. R1:强化学习推理的技术突破与应用前景

&#x1f4cc; 引言&#xff1a;AI 推理的新时代 近年来&#xff0c;大语言模型&#xff08;LLM&#xff09; 的规模化扩展成为 AI 研究的主流方向。然而&#xff0c;LLM 的扩展是否真的能推动 通用人工智能&#xff08;AGI&#xff09; 的实现&#xff1f;DeepSeek 推出的 R1…...

冲刺蓝桥杯之速通vector!!!!!

文章目录 知识点创建增删查改 习题1习题2习题3习题4&#xff1a;习题5&#xff1a; 知识点 C的STL提供已经封装好的容器vector&#xff0c;也可叫做可变长的数组&#xff0c;vector底层就是自动扩容的顺序表&#xff0c;其中的增删查改已经封装好 创建 const int N30; vecto…...

【视频+图文详解】HTML基础1-html和css介绍、上网原理

图文详解 html介绍 概念&#xff1a;html是超文本标记语言的缩写&#xff0c;其英文全称为HyperText Markup Language&#xff0c;是用来搭建网站结构的语言&#xff0c;比如网页上的文字&#xff0c;按钮&#xff0c;图片&#xff0c;视频等。html的版本分为1.0、2.0、3.0、…...

Deepseek技术浅析(二):大语言模型

DeepSeek 作为一家致力于人工智能技术研发的公司&#xff0c;其大语言模型&#xff08;LLM&#xff09;在架构创新、参数规模扩展以及训练方法优化等方面都达到了行业领先水平。 一、基于 Transformer 架构的创新 1.1 基础架构&#xff1a;Transformer 的回顾 Transformer 架…...

OpenCV 版本不兼容导致的问题

问题和解决方案 今天运行如下代码&#xff0c;发生了意外的错误&#xff0c;代码如下&#xff0c;其中输入的 frame 来自于 OpenCV 开启数据流的读取 """ cap cv2.VideoCapture(RTSP_URL) print("链接视频流完成") while True:ret, frame cap.rea…...

03.04、化栈为队

03.04、化栈为队 1、题目描述 实现一个 MyQueue 类&#xff0c;该类用两个栈来实现一个队列。 2、解题思路 本题要求使用两个栈来实现一个队列。队列遵循先进先出&#xff08;FIFO&#xff09;的原则&#xff0c;而栈遵循后进先出&#xff08;LIFO&#xff09;的原则。因此…...