【问题标题】:What does * beside some steps in explain plan in oracle mean?oracle中解释计划中的一些步骤旁边的*是什么意思?
【发布时间】:2017-01-21 18:44:30
【问题描述】:

3 个表:employees(emp_id、dept_id、job_id、emp_fname、emp_lname、salary、address、email)、departments(dept_id,d_name) 和 jobs(job_id,j_title)。

员工(emp_id)、部门(dept_id)和工作(job_id)的非唯一索引。

SQL> explain plan for 
select d.d_name, j.j_title, count(1) 
from employees e join departments d on e.dept_id=d.dept_id
join jobs j on e.job_id=j.job_id
where e.salary>30000 
group by d.d_name, j.j_title;

SQL>select * from table(DBMS_XPLAN.display);

----------------------------------------------------------------------------------

|身份证 |操作 |姓名 |行 |字节 |成本 (%CPU)|时间 |

------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10 | 890 | 4 (25)| 00:00:01 |
| 1 |   HASH GROUP BY | | 10 | 890 | 4 (25)| 00:00:01 |
| 2 |     NESTED LOOPS | | | | | |
| 3 |       NESTED LOOPS | | 10 | 890 | 3 (0)| 00:00:01 |
| 4 |         NESTED LOOPS | | 10 | 640 | 3 (0)| 00:00:01 |
|* 5 |          TABLE ACCESS FULL | EMPLOYEES | 10 | 390 | 3 (0)| 00:00:01 |
| 6 |           TABLE ACCESS BY INDEX ROWID| JOBS | 1 | 25 | 0 (0)| 00:00:01 |
|* 7 |            INDEX RANGE SCAN | JOBS_JOB_ID | 1 | | 0 (0)| 00:00:01 |
|* 8 |        INDEX RANGE SCAN | DEPT_DEPT_ID | 1 | | 0 (0)| 00:00:01 |
| 9 |       TABLE ACCESS BY INDEX ROWID | DEPARTMENTS | 1 | 25 | 0 (0)| 00:00:01 |

谓词信息(由操作id标识): -------------------------------------------------- -

5 - filter("E"."SALARY">30000)

7 - access("E"."JOB_ID"="J"."JOB_ID")

8 - access("E"."DEPT_ID"="D"."DEPT_ID")

--------------------------------------------------------------------------
  1. 第 5,7 和 9 步的 * 是什么意思?
  2. 3 个嵌套循环在这里的作用是什么?
  3. 步骤 7 和 6 在同一个循环中。为什么第 8 步和第 9 步在执行类似工作时会处于不同的循环中?
  4. 谁能解释一下每个步骤的作用?

【问题讨论】:

  • 这些是指关于应该出现在计划下方的那些步骤的附加优化器注释。
  • 您能详细说明一下吗? @JeffreyKemp
  • 您尚未将整个解释计划复制到您的问题中。编辑您的问题以提供缺失的信息,也许我们可以为您提供帮助。
  • @JeffreyKemp 完成。请帮忙!

标签: oracle sql-execution-plan


【解决方案1】:

正如 Jeffrey 所提到的,这些是有关执行计划的一些附加信息。它们通常出现在where/like(等)条件和HASH JOINS(可能是其他但我不确定)。基本上,优化器希望您提供无法放入解释计划输出的额外信息。

您可以通过在下面运行来自己复制它。

EXPLAIN PLAN FOR
your_query;

然后运行

SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);

输出(就我而言)

-----------------------------------------------------------------------------------
| Id  | Operation        | Name           | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |                |    17 |   187 |     2   (0)| 00:00:01 |
|*  1 |  INDEX RANGE SCAN| EMP_DATA_ENAME |    17 |   187 |     2   (0)| 00:00:01 |
-----------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("ENAME" LIKE 'ZM%')
       filter("ENAME" LIKE 'ZM%')

【讨论】:

    【解决方案2】:
    | 4 |         NESTED LOOPS | | 10 | 640 | 3 (0)| 00:00:01 |
    |* 5 |          TABLE ACCESS FULL | EMPLOYEES | 10 | 390 | 3 (0)| 00:00:01 |
    5 - filter("E"."SALARY">30000)
    

    EMPLOYEES 表中的所有行都将被查询,与SALARY 上给定过滤器匹配的行将被发送到计划的下一步。

    | 6 |           TABLE ACCESS BY INDEX ROWID| JOBS | 1 | 25 | 0 (0)| 00:00:01 |
    |* 7 |            INDEX RANGE SCAN | JOBS_JOB_ID | 1 | | 0 (0)| 00:00:01 |
    7 - access("E"."JOB_ID"="J"."JOB_ID")
    

    从第 5 步发出的每一行都包含员工的 JOB_ID。将为此JOB_ID 探测索引JOBS_JOB_ID(第7 步),并使用ROWID 从JOBS 表中检索相应的行(第6 步)。

    | 3 |       NESTED LOOPS | | 10 | 890 | 3 (0)| 00:00:01 |
    |* 8 |        INDEX RANGE SCAN | DEPT_DEPT_ID | 1 | | 0 (0)| 00:00:01 |
    8 - access("E"."DEPT_ID"="D"."DEPT_ID")
    

    EMPLOYEES 表中的DEPT_ID(之前在步骤 5 中检索到)现在用于探测 DEPT_DEPT_ID 索引(步骤 8)。

    | 2 |     NESTED LOOPS | | | | | |
    | 9 |       TABLE ACCESS BY INDEX ROWID | DEPARTMENTS | 1 | 25 | 0 (0)| 00:00:01 |
    

    DEPT_DEPT_ID 索引中的 ROWID 现在用于从 DEPARTMENTS 表中检索行。

    | 0 | SELECT STATEMENT | | 10 | 890 | 4 (25)| 00:00:01 |
    | 1 |   HASH GROUP BY | | 10 | 890 | 4 (25)| 00:00:01 |
    

    将结果放入哈希表中(使用基于d.d_name+j.j_title 的键),对每条记录进行计数。检索到最后一条记录后,扫描哈希表以返回每个 d_name,j_title 的计数。

    【讨论】:

    • 非常感谢! :) 你能不能告诉我,第 7 步和第 6 步在同一个循环中。为什么第 8 步和第 9 步在执行类似工作时会处于不同的循环中?
    • 没有特别的原因 - 解释计划只是优化器的调试输出,并且有其怪癖。有时,您可能会从类似的执行计划中获得稍微不同的模式。
    猜你喜欢
    • 2020-01-08
    • 2020-11-24
    • 2022-07-21
    • 1970-01-01
    • 2015-11-11
    • 1970-01-01
    • 2018-07-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多