Oracle sql tuning guide 翻译 Part 6-4 --- Hint使用准则和Hint使用报告

19.3.2 Guidelines for Join Order Hints

In some cases, you can specify join order hints in a SQL statement so that it does not access rows that have no effect on the result.

The driving table in a join is the table to which other tables are joined. In general, the driving table contains the filter condition that eliminates the highest percentage of rows in the table. The join order can have a significant effect on the performance of a SQL statement.

19.3.2 连接顺序提示符使用准则

在某些情况下,可以在SQL语句中指定连接顺序提示符,从而避免访问对结果无影响的数据行。

连接中的驱动表是指其他表与之进行连接的基础表。通常来说,驱动表包含能过滤掉表中最高比例数据行的筛选条件。连接顺序对SQL语句的性能会产生显著影响。

Consider the following guidelines:

• Avoid a full table scan when an index retrieves the requested rows more efficiently.

• Avoid using an index that fetches many rows from the driving table when you can use a different index that fetches a small number of rows.

• Choose the join order so that you join fewer rows to tables later in the join order.

在制定连接顺序时可参考以下准则:

•避免在索引能更高效地检索所需行时进行全表扫描

•当存在可获取少量数据行的索引时,避免使用会从驱动表中获取大量数据行的索引

•选择连接顺序时应确保后续连接操作涉及的数据行数量尽可能少

The following example shows how to tune join order effectively:

以下示例展示如何有效优化连接顺序:

  1. Choose the driving table and the driving index (if any).

Each of the first three conditions in the previous example is a filter condition that applies to a single table. The last two conditions are join conditions.

Filter conditions dominate the choice of driving table and index. In general, the driving table contains the filter condition that eliminates the highest percentage of rows. Because the range of 100 to 200 is narrow compared with the range of acol, but the ranges of 10000 and 20000 are relatively large, taba is the driving table, all else being equal.

With nested loops joins, the joins occur through the join indexes, which are the indexes on the primary or foreign keys used to connect that table to an earlier table in the join tree. Rarely do you use the indexes on the non-join conditions, except for the driving table. Thus, after taba is chosen as the driving table, use the indexes on b.key1 and c.key2 to drive into tabb and tabc, respectively.

  1. 选择驱动表及驱动索引(如存在)

前例中的前三个条件均为适用于单表的筛选条件,最后两个条件则为连接条件。

筛选条件主导着驱动表和索引的选择。通常来说,驱动表应包含能过滤掉最高比例数据行的筛选条件。由于100到200的范围与acol列的范围相比较窄,而10000和20000的范围相对较大,在其他条件相同的情况下,taba应作为驱动表。

在使用嵌套循环连接时,连接操作通过连接索引实现,这些索引建立在用于将表与连接树中前序表相连的主键或外键上。除了驱动表外,很少会在非连接条件上使用索引。因此,在选定taba作为驱动表后,应分别使用b.key1和c.key2上的索引来连接tabb和tabc表。

  1. Choose the best join order, driving to the best unused filters earliest.

You can reduce the work of the following join by first joining to the table with the best still unused filter. Therefore, if bcol BETWEEN is more restrictive (rejects a higher percentage of the rows) than ccol BETWEEN, then the last join becomes easier (with fewer rows) if tabb is joined before tabc.

  1. 选择最佳连接顺序,优先连接至具有最佳未使用筛选条件的表

通过首先连接至具有最佳未使用筛选条件的表,可以减少后续连接操作的工作量。因此,如果bcol BETWEEN条件比ccol BETWEEN条件更具限制性(能过滤掉更高比例的数据行),那么先连接tabb表再连接tabc表会使最后的连接操作更为高效(需要处理的数据行更少)。

  1. You can use the ORDERED or STAR hint to force the join order.

  2. 可以使用ORDERED或STAR提示符来强制指定连接顺序。

See Also:

Oracle Database Reference to learn about OPTIMIZER_MODE

另请参阅

Oracle Database Reference 了解OPTIMIZER_MODE参数

19.3.3 Reporting on Hints

An explained plan includes a report showing which hints were used during plan generation.

19.3.3 提示符执行报告

已解析的执行计划包含一份报告,显示在计划生成过程中实际使用的提示符。

19.3.3.1 Purpose of Hint Usage Reports

In releases before Oracle Database 19c, it could be difficult to determine why the optimizer did not use hints. The hint usage report solves this problem.

The optimizer uses the instructions encoded in hints to choose an execution plan for a statement, unless a condition prevents the optimizer from using the hint. The database does not issue error messages for hints that it ignores. The hint report shows which hints were used and ignored, and typically explains why hints were ignored. The most common reasons for ignoring hints are as follows:

19.3.3.1 提示符使用报告的目的

在Oracle Database 19c之前的版本中,很难确定优化器未使用提示符的原因。提示符使用报告解决了这个问题。

优化器使用提示符中编码的指令来选择语句的执行计划,除非某些条件阻止优化器使用该提示符。数据库不会为被忽略的提示符发出错误消息。提示符报告显示哪些提示符被使用和忽略,并通常解释提示符被忽略的原因。忽略提示符的最常见原因如下:

• Syntax errors

A hint can contain a typo or an invalid argument. If multiple hints appear in the same hint block, and if one hint has a syntax error, then the optimizer honors all hints before the hint with an error and ignores hints that appear afterward. For example, in the hint specification /*+ INDEX(t1) FULL(t2) MERG(v) USE_NL(t2) */, MERG(v) has a syntax error. The optimizer honors INDEX(t1) and FULL(t2), but ignores MERG(v) and USE_NL(t2). The hint usage report lists MERG(v) as having an error, but does not list USE_NL(t2) because it is not parsed.

• 语法错误

提示符可能包含拼写错误或无效参数。如果同一提示符块中出现多个提示符,且其中一个提示符存在语法错误,则优化器会遵循错误提示符之前的所有提示符,而忽略之后出现的提示符。例如,在提示符规范/*+ INDEX(t1) FULL(t2) MERG(v) USE_NL(t2) */中,MERG(v)存在语法错误。优化器将遵循INDEX(t1)和FULL(t2),但忽略MERG(v)和USE_NL(t2)。提示符使用报告会将MERG(v)列为存在错误,但不会列出USE_NL(t2),因为该提示符未被解析。

• Unresolved hints

An unresolved hint is invalid for a reason other than a syntax error. For example, a statement specifies INDEX(employees emp_idx), where emp_idx is not a valid index name for table employees.

• 未解析的提示符

未解析的提示符指因语法错误之外的原因而无效的提示符。例如,某语句指定了INDEX(employees emp_idx),而emp_idx并非employees表的有效索引名称。

• Unresolved hints

An unresolved hint is invalid for a reason other than a syntax error. For example, a statement specifies INDEX(employees emp_idx), where emp_idx is not a valid index name for table employees.

• 未解析的提示符

未解析的提示符指因语法错误之外的原因而无效的提示符。例如,某语句指定了INDEX(employees emp_idx),而emp_idx并非employees表的有效索引名称。

• Conflicting hints

The database ignores combinations of conflicting hints, even if these hints are correctly specified. For example, a statement specifies FULL(employees) INDEX(employees), but an index scan and full table scan are mutually exclusive. In most cases, the optimizer ignores both conflicting hints.

•冲突的提示符

即使正确指定了提示符,数据库也会忽略相互冲突的提示符组合。例如,某语句同时指定了FULL(employees)和INDEX(employees),但索引扫描和全表扫描是互斥的操作。在大多数情况下,优化器会忽略所有相互冲突的提示符。

翻译说明:

  1. 用"互斥的操作"传达"mutually exclusive"

• Hints affected by transformations

A transformation can make some hints invalid. For example, a statement specifies PUSH_PRED(some_view) MERGE(some_view). When some_view merges into its containing query block, the optimizer cannot apply the PUSH_PRED hint because some_view is unavailable.

• 受查询转换影响的提示符

查询转换可能导致某些提示符失效。例如,某语句同时指定了PUSH_PRED(some_view)和MERGE(some_view)。当some_view被合并到其所属的查询块后,由于some_view已不存在,优化器将无法应用PUSH_PRED提示符。

See Also:

Oracle Database SQL Language Reference to learn about the syntax rules for comments and hints

另请参阅

Oracle Database SQL Language Reference 了解注释和提示符的语法规则

19.3.3.2 User Interface for Hint Usage Reports

The report includes the status of all optimizer hints. A subset of other hints, including PARALLEL and INMEMORY, are also included.

19.3.3.2 提示符使用报告的用户界面

该报告包含所有优化器提示符的状态信息,同时也会包含包括PARALLEL和INMEMORY在内的其他部分提示符。

Report Access

Hint tracking is enabled by default. You can access the hint usage report by using the following DBMS_XPLAN functions:

报告访问方式

提示符跟踪功能默认处于启用状态。可以通过以下DBMS_XPLAN函数访问提示符使用报告:

• DISPLAY

• DISPLAY_CURSOR

• DISPLAY_WORKLOAD_REPOSITORY

• DISPLAY_SQL_PLAN_BASELINE

• DISPLAY_SQLSET

The preceding functions generate a report when you specify the value HINT_REPORT in the format parameter. The value TYPICAL displays only the hints that are not used in the final plan, whereas the value ALL displays both used and unused hints.

当在format参数中指定HINT_REPORT值时,上述函数将生成相应的报告。TYPICAL值仅显示最终计划中未使用的提示符,而ALL值则同时显示已使用和未使用的提示符。

Report Format

Suppose that you explain the following hinted query:

报告格式

假设需要分析以下包含提示符的查询语句:

The following output of DBMS_XPLAN.DISPLAY shows the plan, including the hint report:

以下DBMS_XPLAN.DISPLAY函数的输出结果显示执行计划,其中包含提示符报告:

The report header shows the total number of hints in the report. In this case, the statement contained 3 total hints. If hints are unused, unresolved, or have syntax errors, then the header specifies their number. In this case, only 1 hint was unused.

报告头部显示报告中提示符的总数量。在本示例中,该语句共包含3个提示符。如果存在未使用、未解析或存在语法错误的提示符,报告头部会特别注明其数量。在本案例中,仅有1个提示符未被使用。

The report displays the hints under the objects (for example, query blocks and tables) that appear in the plan. Before each object is a number that identifies the line in the plan where the object first appears. For example, the preceding report shows hints that apply to the following distinct objects: T1@SEL2, and T1@SEL1. The table T1@SEL2 appears in query block SEL5DA710D3 at line 4 of the plan. The table T1@SEL$1 appears in the same query block at line 5 of the plan.

报告将提示符按执行计划中出现的对象(例如查询块和表)进行分类显示。每个对象前均标有数字标识符,指示该对象在计划中首次出现的位置行号。例如,前述报告显示了应用于以下独立对象的提示符:T1@SEL2和T1@SEL1。其中表T1@SEL2出现在查询块SEL5DA710D3的第4行,而表T1@SEL$1则出现在同一查询块的第5行。

Hints can be specified incorrectly or associated with objects that are not present in the final plan. If a query block does not appear in the final plan, then the report assigns it line number 0. In the preceding example, no hints have line number 0, so all query blocks appeared in the final plan.

提示符可能存在指定错误或关联到最终计划中不存在的对象。如果某个查询块未出现在最终计划中,报告会将其行号标记为0。在前述示例中,所有提示符均未出现行号0的情况,说明所有查询块都已在最终计划中呈现。

The report shows the text of the hints. The hint may also have one of the following annotations:

• E indicates a syntax error.

• N indicates an unresolved hint.

• U indicates that the corresponding hint was not used in the final plan.

报告会显示提示符的原始文本内容。每个提示符可能附带以下注释标记之一:

• E表示存在语法错误

• N表示未解析的提示符

• U表示该提示符未在最终计划中使用

In the preceding example, U - FULL(t1) indicates that query block SEL$5DA710D3 appeared in the final plan, but the FULL(t1) hint was not applied.

在前述示例中,"U - FULL(t1)"的标记表示查询块SEL$5DA710D3虽已出现在最终计划中,但FULL(t1)提示符并未被实际应用。

Within each object, unused hints appear at the beginning, followed by used hints. For example, the report first shows the FULL(t1) hint, which was not used, and then FULL(@sel$2 t1), which was used. For many unused hints, the report explains why the optimizer did not apply the hints. In the preceding example, the report indicates that FULL(t1) was not used for the following reason: hint overridden by another in parent query block.

在每个对象条目下,未使用的提示符会优先显示,随后才是已使用的提示符。例如,报告中首先显示未被使用的FULL(t1)提示符,接着显示已被使用的FULL(@sel$2 t1)提示符。对于多数未使用的提示符,报告会解释优化器未采纳的原因。在前述示例中,报告指出FULL(t1)未被使用的原因是:该提示符已被父查询块中的其他提示符覆盖。

翻译说明:

  1. "已被父查询块中的其他提示符覆盖"传达"hint overridden by another in parent query block"

See Also:

Oracle Database PL/SQL Packages and Types Reference to learn more about the DBMS_XPLAN package

另请参阅

Oracle Database PL/SQL Packages and Types Reference 了解有关DBMS_XPLAN包的更多信息

相关推荐
chenchihwen4 小时前
AI代码开发宝库系列:FAISS向量数据库
数据库·人工智能·python·faiss·1024程序员节
小光学长4 小时前
基于Vue的课程达成度分析系统t84pzgwk(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
前端·数据库·vue.js
摇滚侠5 小时前
全面掌握PostgreSQL关系型数据库,备份和恢复,笔记46和笔记47
java·数据库·笔记·postgresql·1024程序员节
周杰伦fans5 小时前
Navicat - 连接 mysql 、 sqlserver 数据库 步骤与问题解决
数据库·mysql·sqlserver
码以致用6 小时前
StarRocks笔记
数据库·starrocks·olap·1024程序员节
auspicious航6 小时前
PostgreSQL数据库关于pg_rewind的认识
数据库·postgresql·oracle
武子康7 小时前
Java-159 MongoDB 副本集容器化 10 分钟速查卡|keyfile + –auth + 幂等 init 附 docker-compose
java·数据库·mongodb·docker·性能优化·nosql·1024程序员节
zz-zjx7 小时前
MySQL 索引深度指南:原理 · 实践 · 运维(适配 MySQL 8.4 LTS)
运维·数据库·mysql
摇滚侠7 小时前
全面掌握PostgreSQL关系型数据库,设置远程连接,笔记05,笔记06
java·数据库·笔记·postgresql