【问题标题】:Oracle: How to estimate the size of a view?Oracle:如何估计视图的大小?
【发布时间】:2022-02-12 09:22:30
【问题描述】:

在 Oracle 中,我可以get the size of a table。我想估计一个视图的大小(非物化)。有可能吗?

我知道视图本身没有任何数据,但我们正在将数据移动到我们的数据湖并希望对其进行估计。了解规模后,我们将能够优化资源并加快流程

【问题讨论】:

  • 这很简单:大小为 0 - 视图不存储任何数据
  • Hi Views 是简单的存储(编译)查询,可以在需要时执行,但它们不存储数据,它们会从底层表中获取存储的数据。
  • 非物化视图不是“执行”的,而只是在主查询中“组合”。
  • 我知道视图本身没有任何数据,但我们正在将数据移动到我们的数据湖并想对其进行估计。了解规模后,我们将能够优化资源并加快流程

标签: oracle schema


【解决方案1】:

您可以使用EXPLAIN PLAN 来估计读取整个视图将返回的字节数和行数。但请记住,这些数字只是估计值,它们取决于当前的统计数据,对于更复杂的查询,它们的准确性会降低。

例如,在我的系统上,EXPLAIN PLAN 估计有点复杂的元数据视图将返回 34 MB 和 75,590 行。而实际值大约为 14 MB 和 85,402 行。

命令:

explain plan for select * from dba_objects;

select * from table(dbms_xplan.display);

结果:

Plan hash value: 3423780594
 
------------------------------------------------------------------------------------------------------------
| Id  | Operation                              | Name              | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                       |                   | 75590 |    34M|   134K  (1)| 00:00:06 |
|   1 |  VIEW                                  | DBA_OBJECTS       | 75590 |    34M|   134K  (1)| 00:00:06 |
|   2 |   UNION-ALL                            |                   |       |       |            |          |
...

在单个查询中估计多个视图

通过一些技巧,您可以在单个查询中为多个视图创建估算值。此解决方案需要 Oracle 12.1 或更高版本。 WITH FUNCTION 语法有点奇怪,一些 IDE 很难处理它,所以你可能不得不在结尾处使用分号和斜线。

--Create sample views from data dictionary views. 
create or replace view view1 as select * from all_tables;
create or replace view view2 as select * from all_tab_privs;
create or replace view view3 as select * from all_objects;

--Get the estimated size of each query. The actual values will differ for your database.
with function get_bytes(p_view_name varchar2) return number is
    v_bytes number;
    --(Needed because "explain plan" is technically DML, which normally shouldn't be executed inside a query.)
    pragma autonomous_transaction;
begin
    --Create an explain plan for reading everything from the view.
    execute immediate replace(q'[explain plan set statement_id = '#VIEW_NAME#' for select * from #VIEW_NAME#]', '#VIEW_NAME#', p_view_name);

    --Get the size in bytes.
    --Latest plan information. (In case the explain plan was generated multiple times.)
    select max(bytes)
    into v_bytes
    from
    (
        --Plan information.
        select bytes, timestamp, max(timestamp) over () latest_timestamp
        from plan_table
        where statement_id = p_view_name and id = 0
    )
    where latest_timestamp = timestamp;

    --As part of the AUTONOMOUS_TRANSACTION feature, the function must either commit or rollback.
    rollback;

    return v_bytes;
end;
select view_name, round(get_bytes(view_name) / 1024 / 1024, 1) mb
from user_views
order by mb desc, view_name;
/

结果:

VIEW_NAME            MB
------------ ----------
VIEW3               2.4
VIEW1                .8
VIEW2                .7

【讨论】:

  • 感谢您的回答。看起来我必须始终执行选择视图的查询才能选择 dbms_xplan。对吗?
  • @neves 没错。如果你只有十几个表,手动运行它可能是最快的。如果您有一千个表,可能值得创建一个更高级的查询来一次性完成所有操作。如果您需要更自动化的解决方案,请告诉我。
  • 如果您能帮助实现自动化,我将不胜感激。我真正需要的是按大小对模式视图进行排序。
  • @neves 查看更新后的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-11
  • 2010-09-09
  • 1970-01-01
  • 1970-01-01
  • 2016-03-21
  • 2012-09-16
相关资源
最近更新 更多