【问题标题】:Oracle 12c - view plans access unnecessary tablesOracle 12c - 查看计划访问不必要的表
【发布时间】:2022-01-25 04:47:17
【问题描述】:

我希望能解释一些视图 + 优化器的行为

让我们做一个这样的视图

select e.employee_name, e.employee_active, ei.marital_status
    from employees e
    left join employee_info ei on ei.employee_id = e.employee_id

然后让我们像这样访问它

select distinct employee_name from employee_view where employee_id = 13

在我的脑海中,我认为我们根本不需要访问employee_info 表就可以以功能正确的方式执行此查询。然而,当我解释这个查询的计划时,我看到它访问了employee_info。我是否遗漏了一些需要实际执行该连接的东西?如果它在功能上等同于不打那张桌子,有没有办法阻止这种情况在 12c 中发生?

【问题讨论】:

  • 根据定义,视图只不过是存储在数据库中的已解析 SQL,当您查询视图时,它实际上执行查询然后返回数据。如果您只想从员工表中选择员工姓名,那么为什么不创建一个仅从员工表中选择的视图,然后该视图将访问员工表。
  • 请提供表定义,包括PKFK和视图定义。您的 example 视图查询不包含 employee_id 导致 ORA-00904: "EMPLOYEE_ID": invalid identifier

标签: oracle view oracle12c


【解决方案1】:

推演基本上是正确的,但你必须考虑到不是每个优化可能也是实现。

Oracle 务实地观察潜力并决定应该在哪里扩展优化。

例如,有时谓词 where 1=1 and ... 可能会使优化器感到困惑,但由于这种“构造”被经常使用,在最近的版本中,优化器识别它并忽略它而没有副作用。

您的 outer 连接到子列的设置,而仅从父列中选择 distinct 可能不是很频繁,因此尚未涵盖。

这是一个类似的例子,Oracle 可以从视图中跳过一个表(注意 PKFK 的定义,这是关键

create table employees (
employee_id  int primary key,
employee_name varchar2(10),
employee_active varchar2(10));

create table employee_info (
employee_id int,
marital_status varchar2(10));

alter table employee_info
add constraint emp_info_fk1 foreign key (employee_id)
references employees (employee_id);

create or replace view employee_view as
select e.EMPLOYEE_ID, e.employee_name, e.employee_active, ei.marital_status
    from employees e
    join employee_info ei on ei.employee_id = e.employee_id;

查询select marital_status from employee_view where employee_id = 13可以跳过employees(父)表,只访问子表

-----------------------------------------------------------------------------------
| Id  | Operation         | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |               |     1 |    20 |     2   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| EMPLOYEE_INFO |     1 |    20 |     2   (0)| 00:00:01 |
-----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
 
    1 - filter("EI"."EMPLOYEE_ID"=13)

更多信息和链接在similar answer

【讨论】:

    猜你喜欢
    • 2016-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-05
    • 1970-01-01
    相关资源
    最近更新 更多