Oracle 如何处理给定的 SQL 语句
Posted
技术标签:
【中文标题】Oracle 如何处理给定的 SQL 语句【英文标题】:How Oracle processes the given SQL statement 【发布时间】:2015-04-04 17:23:17 【问题描述】:您能否解释一下查询将如何执行?请逐步解释...
select
max(salary),
country_id
from (
select
salary,
department_id,
location_id,
country_id
from
HR.EMPLOYEES
natural join
HR.DEPARTMENTS
natural join
HR.LOCATIONS
)
group by country_id;
【问题讨论】:
优化器将根据它对您的机器和数据细节的了解来确定执行的分步指令。 生成解释计划并自己分析。 我不认为它会被执行。我认为它会引发ORA-00918: column ambiguously defined
错误。
@DavidFaber 为什么?子查询只有一层深。它执行得很好。我在回答中使用了相同的查询。
【参考方案1】:
了解SQL执行步骤的最好方法是生成解释计划,从最里面的ID
到最外面的分析。
SQL> explain plan for
2 select
3 max(salary),
4 country_id
5 from (
6 select
7 salary,
8 department_id,
9 location_id,
10 country_id
11 from
12 HR.EMPLOYEES
13 natural join
14 HR.DEPARTMENTS
15 natural join
16 HR.LOCATIONS
17 )
18 group by country_id;
Explained.
SQL>
让我们以可读的格式显示解释计划:
SQL> SELECT * FROM TABLE(dbms_xplan.display);
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------
Plan hash value: 1571404374
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 11 | 297 | 8 (0)| 00:00:01 |
| 1 | HASH GROUP BY | | 11 | 297 | 8 (0)| 00:00:01 |
|* 2 | HASH JOIN | | 11 | 297 | 8 (0)| 00:00:01 |
| 3 | MERGE JOIN | | 11 | 176 | 5 (0)| 00:00:01 |
| 4 | TABLE ACCESS BY INDEX ROWID| LOCATIONS | 23 | 138 | 2 (0)| 00:00:01 |
| 5 | INDEX FULL SCAN | LOC_ID_PK | 23 | | 1 (0)| 00:00:01 |
|* 6 | SORT JOIN | | 11 | 110 | 3 (0)| 00:00:01 |
|* 7 | TABLE ACCESS FULL | DEPARTMENTS | 11 | 110 | 3 (0)| 00:00:01 |
| 8 | TABLE ACCESS FULL | EMPLOYEES | 107 | 1177 | 3 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("EMPLOYEES"."DEPARTMENT_ID"="DEPARTMENTS"."DEPARTMENT_ID" AND
"EMPLOYEES"."MANAGER_ID"="DEPARTMENTS"."MANAGER_ID")
6 - access("DEPARTMENTS"."LOCATION_ID"="LOCATIONS"."LOCATION_ID")
filter("DEPARTMENTS"."LOCATION_ID"="LOCATIONS"."LOCATION_ID")
7 - filter("DEPARTMENTS"."MANAGER_ID" IS NOT NULL)
Note
-----
- this is an adaptive plan
28 rows selected.
SQL>
查询转换器可以决定是否重写查询,以便优化器可以生成更好的执行计划。
来自documentation:
估算器
估算器确定给定执行计划的总成本。 估计器生成三种不同类型的度量来实现 这个目标:
选择性
此度量表示行集中的一小部分行。选择性与查询谓词相关联,例如 last_name='Smith', 或谓词的组合。
基数
此度量表示行集中的行数。
费用
此度量表示使用的工作单元或资源。查询优化器使用磁盘 I/O、CPU 使用率和内存使用率作为工作单元。
如果统计信息可用,则估算器使用它们来计算 措施。统计数据提高了准确度 措施。
我建议阅读我上面提供的文档链接。
【讨论】:
以上是关于Oracle 如何处理给定的 SQL 语句的主要内容,如果未能解决你的问题,请参考以下文章