3

In Oracle I can get the size of a table. I would like to estimate the size of a view (non materialized). Is it possible?

I know that views don't have any data per se, but we are moving the data to our data lake and would like to estimate it. Knowing the size we will be able to optimize our resources and speed up the process

neves
  • 33,186
  • 27
  • 159
  • 192
  • 4
    That's easy: the size is 0 - a view doesn't store any data –  Feb 08 '22 at 22:09
  • Hi Views are simply stored (compiled ) queries that can be executed when needed, but they don't store data, they will get the data stored from the underlying tables. – Himanshu Kandpal Feb 08 '22 at 22:13
  • Non-materialized view are not "executed" but just "combined" in the main query. – The Impaler Feb 09 '22 at 00:18
  • I know that views don't have any data per se, but we are moving the data to our datalake and would like to estimate it. Knowing the size we will be able to optimize our resources and speed up the process – neves Feb 09 '22 at 20:14

1 Answers1

2

You can use EXPLAIN PLAN to estimate the number of bytes and rows that will be returned by reading the entire view. But keep in mind that these numbers are only estimates, they depend on having current statistics, and they will be less accurate for more complicated queries.

For example, on my system, EXPLAIN PLAN estimates that a somewhat complicated metadata view will return 34 MB and 75,590 rows. Whereas the actual values are roughly 14 MB and 85,402 rows.

Commands:

explain plan for select * from dba_objects;

select * from table(dbms_xplan.display);

Results:

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                            |                   |       |       |            |          |
...

Estimate multiple views in a single query

With a few tricks you can create estimates for multiple views all within a single query. This solution requires Oracle 12.1 or higher. The WITH FUNCTION syntax is a bit odd, and some IDEs struggle with it, so you might have to play around with the semicolon and slash at the end.

--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;
/

Results:

VIEW_NAME            MB
------------ ----------
VIEW3               2.4
VIEW1                .8
VIEW2                .7
Jon Heller
  • 34,999
  • 6
  • 74
  • 132
  • 1
    Thanks for the answer. It looks like I must always execute a query selecting the view to be able to select the dbms_xplan. Correct? – neves Feb 10 '22 at 18:48
  • @neves That is correct. If you only have a dozen tables it's probably fastest to run it all manually. If you have a thousand tables, it might be worth creating a fancier query to do it all in one shot. Let me know if you need a more automated solution. – Jon Heller Feb 10 '22 at 20:26
  • I'd be really grateful if you can help to automate. What I really need is to order my schema views by size. – neves Feb 11 '22 at 15:51
  • @neves See the updated answer. – Jon Heller Feb 12 '22 at 01:22