Oracle 在尝试从 2 个现有视图创建表或物化视图时非常慢

问题描述 投票:0回答:1

我有一个经典的 Oracle 视图,称为

STAFFACTIVE
,其中包含大约 9500 行,每行 10 个小型本机数据类型字段(仅限数字和 varchar2(100))。 该视图基于来自 DBLINK2 个表构建。 运行时间不到一秒。

我有另一个名为

DEPT_STAFFACTIVE
的视图,其中包含大约 350 行,每行 3 个字段(1 个数字和 2 个 varchar(100))。该视图基于来自本地模式的 1 个表 构建。 几毫秒内运行。

我创建了一个连接这两个视图的视图,没问题。运行时间为 ± 3 秒:

CREATE OR REPLACE FORCE VIEW V_STAFF
(
    ID,
    LOGIN,
    FIRSTNAME,
    LASTNAME,
    SEARCH_FIRSTNAME,
    SEARCH_LASTNAME,
    PROPER_FIRSTNAME,
    PROPER_LASTNAME,
    EMAIL
)
    BEQUEATH DEFINER
AS
    SELECT pers_id                         AS id,
           logn_login                      AS login,
           rich_first_name            AS firstname,
           rich_family_name           AS lastname,
           search_first_name          AS search_firstname,
           search_family_name         AS search_lastname,
           INITCAP (rich_first_name)  AS proper_firstname,
           INITCAP (rich_family_name) AS proper_lastname,
           email
      FROM staffactive LEFT JOIN dept_staffactive ON staffactive.pers_id = dept_staffactive.pers_id;

但由于 3 秒有点太慢,我想使用 TABLEMATERIALIZED VIEW 来代替。

问题:如果尝试

CREATE TABLE T_STAFF as SELECT * FROM V_STAFF
或者,如果我尝试基于 select * from V_STAFF 创建物化视图,那么 它会运行超过一分钟

在语句中写JOIN时也会出现同样的问题

create table t_staff as select * from staffactive left join dept_staffactive on staffactive.pers_id = dept_staffactive.pers_id

有什么理由吗?哪里慢了?有没有工具可以分析这个?

我知道基于 2 个底层视图

V_FINAL
STAFFACTIVE
构建视图
DEPT_STAFFACTIVE
有点奇怪,但由于它们已经存在,为什么不使用它们呢?

oracle query-optimization sql-view materialized-views
1个回答
0
投票

你的物化视图实际上是在创建一个表(一个堆段),写入本地数据库。每当您写入数据库(DML 或 CTAS)时,Oracle 都必须使本地数据库成为驱动站点(并且它将忽略使用

driving_site
提示更改此设置的尝试)。

这意味着 Oracle 无法将本地表中的行

DEPT_STAFFACTIVE
发送到远程端以进行远程哈希联接。相反,它必须将远程
STAFFACTIVE
数据拉到本地并在本地执行连接。如果由于视图复杂性而无法估计行数,则可能会认为移动该数据的成本太大,而是选择嵌套循环操作,该操作将一次又一次地为中的每一行执行视图代码
DEPT_STAFFACTIVE.
鉴于这些视图的尺寸很小,这可能就是它正在做的事情。

我建议暗示强制进行哈希连接:

create table t_staff as 
select /*+ no_merge(staffactive) no_merge(dept_staffactive) use_hash(staffactive dept_staffactive) */ * 
from staffactive left join dept_staffactive on staffactive.pers_id = dept_staffactive.pers_id
© www.soinside.com 2019 - 2024. All rights reserved.