Skip to Main Content
  • Questions
  • Materialized view V/s User created Summary table.

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Venkat.

Asked: October 16, 2004 - 4:04 pm UTC

Last updated: January 17, 2012 - 11:41 am UTC

Version: 9.2.0

Viewed 10K+ times! This question is

You Asked

Hi Tom,

I need prepare a document which should talk about materialized view and summary table (User explicitily created). I would like to know pros and cons of both of these. Atleast some 10 points on both of these.

If i tell anybody about materialized view then i need some substantial reasons to convince them why i should go for materialized views.

I hope you got my problem, Could you please help me.

Thanks in advance.

Thanks
Venkat


and Tom said...

Hmm, "10" -- what I would want (technically speaking) would be 1 superb reason -- vs 10 really weak or "not smart" reasons for somthing.

It is not a debate really -- you either use the feature or not.

Since there is no such thing as a "user create summary" -- there are just tables created by users with no meta data about them, no control, no management, no administration (how about anti-reasons?). I mean, a table T created as select from 14 tables is just "table t". You don't know the defining query (gone are those details), you don't know if the information is even relatively current (gone is that detail), your end user has to understand the fine art of "indexing intelligently", and so on. I see virtually nothing "positive" letting end users create tables willy-nilly.

MV's on the other hand

o behave like indexes for a data warehouse, they automagically are used when useful - end users don't have to be trained to use them -- they just are used

o can be recommended by the system (as it watches you run queries -- it can say "you know, if you had this MV in place..."

o contain the meta data about whence they came from (the defining queries, the dependencies)

o know when they are 'stale'

o know how to incrementally refresh themselves

o can be administered professionally (scheduled for refreshes, maintained actually)

o can be incrementally refreshed even better with partitioning (partition change tracking)

see:

</code> http://docs.oracle.com/cd/B10501_01/server.920/a96520/toc.htm <code>

and get as many reasons as you like I guess.


I (as an administrator) see zero advantages to end users creating tables, maintaining tables. As an end user I see no advantages (heck, I just became a DBA if i start doing that -- only a DBA that doesn't get told when the base data is refreshed and so on)




Rating

  (20 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

David Aldridge, October 16, 2004 - 7:01 pm UTC

There's a couple of issues that I've had in the past that I'd just like to mention here ...

i) When a materialized view refreshes it is not possible to specify an ORDER BY clause (except on initial creation). This stops us from implementing a physical order for the rows in the summary table, and we lose the ability to cluster the rows for better query performance or compression.

ii) I've had situations where a summary table based on fast refresh and PCT has just emptied itself during the refresh process ... it only has to happen a couple of times and you find that it's prudent to have a standby method for repopulating the summary table, especially if you don't have the resources to do a complete refresh (temp space mainly), but it can be a painful conversation explaining how all that data disappeared.



Tom Kyte
October 16, 2004 - 8:31 pm UTC

i) unless you use a mv on a prebuilt object such as a table in a cluster or an IOT - sure........ (eg: you can get physical ordering if you need it)

ii) if that happened did you (please say yes) file a tar/bug??? things will never get fixed unless we (we -- collective we) report them.

David Aldridge, October 17, 2004 - 12:43 am UTC

>> i) unless you use a mv on a prebuilt object such as a table in a cluster or an IOT - sure........  (eg: you can get physical ordering if you need it)

Ah quite so, but you use clustering at the expense of partitioning, no?

SQL> create cluster obj (OBJECT_TYPE VARCHAR2(19),OWNER VARCHAR2(30))
  2  single table hashkeys 2000;

Cluster created.

SQL>
SQL> create table obj_t cluster obj (OBJECT_TYPE,OWNER)
  2  compress
  3  partition by range (object_name)
  4  (partition p1 values less than ('M'),
  5  partition p1 values less than (MAXVALUE))
  6  as select * from all_objects;
partition by range (object_name)
*
ERROR at line 3:
ORA-14026: PARTITION and CLUSTER clauses are mutually exclusive

... or is there an alternative method that would work for that? The maintenance and performance advantages of partitioning are a tough loss.

I was testing compression on a cluster, and noted that the server allowed the syntax to define the table as compressed but there didn't seem to be any effect ...

SQL> set feedback off
SQL>
SQL> drop table obj_t;
SQL> drop cluster obj;
SQL>
SQL> create cluster obj (OBJECT_TYPE VARCHAR2(19),OWNER VARCHAR2(30))
  2  single table hashkeys 2000;
SQL>
SQL> create table obj_t cluster obj (OBJECT_TYPE,OWNER)
  2  nocompress
  3  as select * from all_objects;
SQL>
SQL>
SQL> analyze table obj_t compute statistics for table;
SQL> select blocks,empty_blocks from user_tables where table_name = 'OBJ_T';

    BLOCKS EMPTY_BLOCKS
---------- ------------
      2584            8
SQL>
SQL>
SQL> drop table obj_t;
SQL> drop cluster obj;
SQL>
SQL> create cluster obj (OBJECT_TYPE VARCHAR2(19),OWNER VARCHAR2(30))
  2  single table hashkeys 2000;
SQL>
SQL> create table obj_t cluster obj (OBJECT_TYPE,OWNER)
  2  compress
  3  as select * from all_objects;
SQL>
SQL> analyze table obj_t compute statistics for table;
SQL> select blocks,empty_blocks from user_tables where table_name = 'OBJ_T';

    BLOCKS EMPTY_BLOCKS
---------- ------------
      2584            8
SQL> alter table obj_t add (my_col number);
SQL>
SQL> SQL> drop table obj_t;
SQL>
SQL> create table obj_t
  2  nocompress
  3  as select * from all_objects;
SQL>
SQL> analyze table obj_t compute statistics for table;
SQL> select blocks,empty_blocks from user_tables where table_name = 'OBJ_T';

    BLOCKS EMPTY_BLOCKS
---------- ------------
       549           27
SQL> alter table obj_t add (my_col number);
SQL>
SQL> drop table obj_t;
SQL> create table obj_t
  2  compress
  3  as select * from all_objects;
SQL>
SQL> analyze table obj_t compute statistics for table;
SQL> select blocks,empty_blocks from user_tables where table_name = 'OBJ_T';

    BLOCKS EMPTY_BLOCKS
---------- ------------
       155            5
SQL>


With an IOT you need the mapping table as well, in order to be able to support bitmap indexes. However, it seems like a partitioned IOT + a mapping table + bitmap indexes + a materialized view + PCT fast refresh + query rewrite has the potential for problems -- I'm not saying it wouldn't work, but my own preference is avoid mixing so many features in a single object. Just a personal thing. 

>> ii) if that happened did you (please say yes) file a tar/bug??? things will never get fixed unless we (we -- collective we) report them. 

Absolutely, yes, but Oracle Support wouldn't look at it without a copy of the table + MV etc., a 150Gb export of sensitive gov't data. Since we felt that we had to revert to other means to populate the summaries anyway, we ended up sticking with our alternative solution.

Speaking of which ... an alternative that we felt protected our summary MV and got us the physical row ordering/partitioning etc that we wanted was to ...

i) Load the new fact data into a non-partitioned table (pending later partition exchange)
ii) Summarize the new data to a non-partitioned summary table.
iii) Partition-exchange into the fact table
iv) Partition-exchange into the summary table, on which was defined a never-refresh MV with query rewrite enabled
v) Mark the summary MV as fresh.

That's just an fyi -- it's what we could do in our own circumstances to workaround our own problems.

btw, Oracle Support could really use some people who understand summary MV's and query rewrite ... just IMHO ;) 

Tom Kyte
October 17, 2004 - 9:59 am UTC

IOT"s are a valid approach to "clustering" as well -- they support partitioning.

compression works only on BULK DIRECT PATH operations -- clusters do not support direct pathing.

the point was -- if clustering is something you needed -- you can use clusters, you can use IOT's. It may or may not preclude something else -- but hey.

And yes -- your approach is valid as well -- you get the advantages of the MV rewrites and total control over the "order of the data"

performance??? “Materialized view V/s User created Summary table “

Omar, October 17, 2004 - 6:45 am UTC

Tom,

IMHO you explained how Materialized views are better in terms of maintainability.
But who about giving some information on the topic “Materialized view V/s User created Summary table “ regarding performance?.

Btw User created Summary tables a.k.a “cheat tables” (demoralized tables updated by programmer written triggers for reporting purposes ) are regarded better performance wise by some experienced Oracle professionals .

I am working on web based project in which response time and performance needs are very high . my project lead has told me explicitly to use “cheat tables” instead of MV’s
Where ever possible because “cheat tables” are better performance wise for reports that
Require both real time (recent ) & historical data. The reason he has giving me is that when you Require both real time( recent ) & historical data for a report the MV’s have an overhead of MV’s Logs that’s why “cheat tables” would perform better in this case.

Kindly give some performance comparison of both MV's & "cheat tables"

Thanks


Tom Kyte
October 17, 2004 - 10:11 am UTC

did you see point #1? they act like INDEXES, end users don't have to be trained on them.

"some experienced Oracle professionals"

I too fall into that camp, however I fall into the lazy camp, the one that says

"the less code I write, is the less code I maintain"

HOW HOW HOW could they "perform better" at query time? riddle me that batman. think about it. a table is a table is a table. huh.


if you think MV logs are overhead -- ask this person "so, the internal optimized triggers in C that Oracle wrote are slower and consume more resources than the interpreted, plsql code we develop ourselves. Cool"


Please you give ME a comparision -- I cannot fight religion. If your lead loves to write code, nothing we can do to help you.

mvs

A reader, October 17, 2004 - 11:36 am UTC

They seem to be an excellent tool from what I have
read and experimented with. One place where I found
you can not use them to summarize is when you need history of data but the underlying data gets purged earlier than
your longest history period.

e.g.
you have a table that stores hourly data
the hourly data is rolled up into daily, weekly, monthly.
and you want to retain the daily data for 2 months,
weekly for a quarter and yearly for a year.
however, you want to purge your hourly data every 3 weeks, say,- since it is hourly - it has too many data points
to be retained for a year. In this case, since your
base data (i.e. thr hourly data) does not exist after 3 weeks but you need it for a year max, you have to use tables.


performance??? “Materialized view V/s User created Summary table “

Omar, October 17, 2004 - 11:55 am UTC

Tom,
There was a question on your list "Is materialized view synchronization cheap?", version 9i

</code> http://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:1366330858675, <code>

And you said :

“I would say that there are three cases:

1) MV's that refresh on commit. These are NOT candidates for OLTP systems.
Why? Predominant one is concurrency. An MV is usually a rollup. Say you have
that "sum(sal) from emp" MV. Upon the update of the EMP table -- every
transaction will SERIALIZE on the refresh of the MV. It would be a big choke point. “


So, if we have a report requirement that needs to get summarized data from e.g 10 tables
We will have to create MV logs for these 10 tables that would keep track of the changes in these 10 tables and then on commit the MV would be refreshed. Your point on the “internalized triggers “is great but as you mentioned in the link mentioned above won’t this be a “ big choke point “ ??

While in the case of “cheat tables” only the triggers would do the trick and update one “cheat table” and no over head of 10 MV logs synchronization + one MV refresh ??

Thanks in Advance

Tom Kyte
October 17, 2004 - 12:35 pm UTC

and won't "doing it yourself via triggers at the STATEMENT level (at least an MV does it upon commit -- the choke point is upon commit -- not row by slow row) be *even worse*"


tell you what -- benchmark it. that is what I would do.

Materialized view V/s User created Summary table

Venkat, October 17, 2004 - 12:27 pm UTC

Hi Tom,

Thank you so much.
I am not really debating on this. But you know when i tell this tell to people, they start debating. Now I can go and even debate with them (Just kidding ;)

Thanks again tom for your help.

Venkat


On MV Refreshes

John Flack, November 16, 2004 - 8:53 am UTC

We had a problem with a failed refresh leaving the MV empty too - that is until we read the docs carefully. Turns out that it won't happen if you refresh in a refresh group, instead of directly. Yes, it does seem silly having a refresh group with one member, but that is the way to go.

Partitioned Materialized View

Jasbir Kular, November 18, 2004 - 2:33 pm UTC

Is it possible to only refresh a single partition of a partitioned materialized view?

Tom Kyte
November 18, 2004 - 2:46 pm UTC

check out the data warehousing guide -- it discusses all of the in's and outs of partitioning, partition change tracking and so on with MV's.


can we maintain a mv partition by partition? yes.


Partitioned Materialized View

Jasbir Kular, November 18, 2004 - 3:15 pm UTC

My MV is refreshed on demand and has three partitions p1, p2, and p3. I would like to refresh partition p1 only even though p2 and p3 have stale rows. Using the DBMS_MVIEW.REFRESH how would I do this? The DW guide on MVs doesn't seem to address this question.

Thanks.

Tom Kyte
November 19, 2004 - 9:54 am UTC

not going to happen, really -- doesn't even seem to make sense. (perhaps that is why the guide doesn't address it, it doesn't work that way)

what is the business case for wanting a MV that is partially fresh but not all of the way fresh?

To Jasbir Kular

Peter, November 19, 2004 - 10:23 am UTC

I'm with Tom, there. Think, what does it mean to have two stale partitions and one fresh one, how would your users see the MV - stale tolerated? Then how would they know to ignore "that" item of data because it has not been updated?

I could think of a couple of reasons to update a single partition - perhaps the source table has less 'history' than the view, but then this type of update needs to be done 'by hand' and not using the refresh functionality. Likewise if you have a tree of partitioned MVs and replace a whole partition in your source fact table you may want to roll-your-own single partition direct-path inserts as Fast refresh under 9.2 and before does not use a truncacte partition + direct path insert and gets bogged with a large amount of deletes.

Partially Refresh MV Partition

Jasbir Kular, November 19, 2004 - 11:21 am UTC

Tom,

The business case is based on a business reporting need. In short, there is a general ledger financial system. One table has transactions and another table has balances. New transactions are appended to the transaction table and the balances are updated based on summarization rules of the transactions. There is a DW that the report users will use to view the balances and transaction data. The business requirement is to only report on specific balances, the report users don't even want to see changes on balances that they are not currently reporting on (but changes to other balances may cause rollup amount data discrepancies). I am researching different options to build a copy of the balances on the DW that is only refreshed for certain grouping of balances. Furthermore, these balances amounts will be in sync with the transactions extracted to DW.

Peter, my question is not performance related.

Thanks.

Tom Kyte
November 19, 2004 - 12:05 pm UTC

sounds like two MV's to me.

A reader, November 21, 2004 - 2:37 am UTC

Tom,

In one of the above posting :

v) Mark the summary MV as fresh.


Can we manually mark the mv as fresh? .. what does it mean there actually ..

Thanks


Tom Kyte
November 21, 2004 - 9:13 am UTC

see alter materialized view in the sql reference.

there is a "consider fresh"

MV on IOT

Yuan, November 19, 2010 - 1:44 pm UTC

"i) unless you use a mv on a prebuilt object such as a table in a cluster or an IOT - sure........
(eg: you can get physical ordering if you need it)"

We built MVs on IOTs in 10g, and when we upgraded to 11g they still work. However, when we try to create a new MV on an IOT in 11g (Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production), we get

ORA-12082: "PWRADMIN"."MV_FTR_DAILY_NODE_DATA" cannot be index organized

Is there something new in 11g that we should be using instead?

Tom Kyte
November 20, 2010 - 5:15 am UTC

give example that worked in 10g but not in 11g for us to look at. make example AS SMALL AS POSSIBLE (you need maybe two columns probably - not hundreds - no tablespace clauses - etc - something anyone can run)

Sample MV on IOT

Yuan, November 22, 2010 - 9:02 am UTC

CREATE TABLE Test_Table (Cd VARCHAR2(50), PRIMARY KEY (Cd))
/
CREATE TABLE Test_IOT (Cd VARCHAR2(50), "COUNT(*)" NUMBER, PRIMARY KEY (Cd)) ORGANIZATION INDEX
/

CREATE MATERIALIZED VIEW Test_IOT ON PREBUILT TABLE AS
SELECT Cd, COUNT(*) FROM Test_Table GROUP BY Cd
/

Tom Kyte
November 23, 2010 - 12:54 pm UTC

got a cut a paste that shows your work?

ops$tkyte%ORA11GR2> select * from v$version;

BANNER
-------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
PL/SQL Release 11.2.0.1.0 - Production
CORE    11.2.0.1.0      Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production

ops$tkyte%ORA11GR2> CREATE TABLE Test_Table (Cd VARCHAR2(50), PRIMARY KEY (Cd))
  2  /

Table created.

ops$tkyte%ORA11GR2> CREATE TABLE Test_IOT (Cd VARCHAR2(50), "COUNT(*)" NUMBER, PRIMARY KEY (Cd))
  2  ORGANIZATION INDEX
  3  /

Table created.

ops$tkyte%ORA11GR2> 
ops$tkyte%ORA11GR2> CREATE MATERIALIZED VIEW Test_IOT ON PREBUILT TABLE AS
  2  SELECT Cd, COUNT(*) FROM Test_Table GROUP BY Cd
  3  /

Materialized view created.

Feedback

Yuan, November 23, 2010 - 1:35 pm UTC

SQL> select * from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
PL/SQL Release 11.2.0.2.0 - Production
CORE    11.2.0.2.0      Production
TNS for Linux: Version 11.2.0.2.0 - Production
NLSRTL Version 11.2.0.2.0 - Production

5 rows selected.

SQL> CREATE TABLE Test_Table (Cd VARCHAR2(50), PRIMARY KEY (Cd))
  2  /

Table created.

SQL> CREATE TABLE Test_IOT (Cd VARCHAR2(50), "COUNT(*)" NUMBER, PRIMARY KEY (Cd)) ORGANIZATION INDEX
  2  /

Table created.

SQL> 
SQL> CREATE MATERIALIZED VIEW Test_IOT ON PREBUILT TABLE AS
  2  SELECT Cd, COUNT(*) FROM Test_Table GROUP BY Cd
  3  / 
CREATE MATERIALIZED VIEW Test_IOT ON PREBUILT TABLE AS
           *
ERROR at line 1:
ORA-12082: "ENGADMIN"."TEST_IOT" cannot be index organized


SQL> 

Tom Kyte
November 23, 2010 - 3:02 pm UTC

that looks like a "product issue", please contact support

11.2.0.2 vs 11.2.0.1

Yuan, November 23, 2010 - 1:45 pm UTC

We just tried my sample MV on IOT on an 11.2.0.1 DB and it worked fine, just as you showed. This appears to be an 11.2.0.2 issue.javascript:apex.submit('SUBMIT_REVIEW')

MV on IOT (continued)

Yuan, November 30, 2010 - 10:37 am UTC

We contacted Oracle Support about the 11.2.0.2 problem (SR 3-2394910251) and here is their reply:


Generic Note
------------------------
Hi Robert,

Please see the development update:
Definitely as per our document and code this is not a bug but in prior versions this is getting created because of bug 9378935.

IOT is organization is completely related to actual table only not to MView.
That is why we do not allow ORGANIZATION key word with PREBUILT option.
If we are using the PREBUILT option if we want to make IOT Mview we need to make sure that content table is already IOT.

For normal MView we allow this ORGANIZATION key word as part of CREATE MV
.... statement because in this case we internally we fire a query CREATE TABLE ... ORGANIZATION .... that will make That table as IOT and we set our
internal maintenance bits.

Closing this issue duplicate of bug 9378935.
Because the main bug here is it is not raising the error ORA-12082 in 10.2.0.5 and 11.0.2.0.1.

Tom Kyte
November 30, 2010 - 12:17 pm UTC

I disagree with their analysis.

that bug is about a flag not getting set correctly in the dictionary when creating a materialized view on a prebuilt IOT. It is not about making it illegal.

I'm traveling too much this week to followup on this - but if you ping me next week, I will.

I would suggest you ask them to re-read the bug and tell you exactly where in the bug it mentions anything about the fix being to "make the IOT illegal". It does not. In fact the bug itself demonstrates that prebuilt IOTS are ok.

MV on IOT (continued)

Yuan, December 15, 2010 - 2:12 pm UTC

Here is the latest response on the SR (3-2394910251):


Oracle Support - December 14, 2010 4:45:48 PM GMT-05:00 [Notes]

Generic Note
------------------------
Hi Robert,

Development say it is expected behaviour in 11.2.0.2.
Please let us know if you have any questions.


MV on IOT (continued)

Yuan, February 04, 2011 - 9:34 am UTC

We got a patch! Thanks Tom for your help!

If anyone else is interested, here's the bug #:

Bug 10329656: CREATE MVIEW ON IOT TABLE WITH PREBUILT TABLE OPTION ERROR ORA-12082 IN 11.2.0.2
Tom Kyte
February 04, 2011 - 10:12 am UTC

Neat - support copied my response above into the bug report and then fixed it ;)


But is there a performance gain of using one over other (table and MV)

Sameer, January 15, 2012 - 6:37 am UTC


Hey Tom,

Thanks for all the woderful tips and clarification you offer to oracle user group. The explanations are really in-depth and always inspire me look at fundamentals before proposing a solution.
You have mentioned some advantages of using MV over table (most of which are manageability issues) But is there any performance gain of using

insert into table T1 select blah blah blah from a set of table

over saying

create materialized view MV1 as select blah blah blah from a set of tables

Given that I am going to disable indexes on T1 and use direct path insert with parallelism (pretty much what MV refresh does in insert phase) before doing insert
Tom Kyte
January 17, 2012 - 11:41 am UTC

a materialized view is simply a table that is refreshed from the source data. It is a table.


If you want this to be managed by the database - you would use a materialized view (which is... just a table)

If you want to do this refreshing on your own, then you wouldn't.

the performance of putting data into a table via a materialized view will be just about the same as your insert /*+ APPEND */ (assuming you refresh with 'atomic_refresh=>false' to enable truncate+direct path load)

More to Explore

VLDB

If you are new to partitioning, check out Connor McDonald's introduction series here.

VLDB

Documentation set on VLDB and Partitioning.