3

I'm being hit hard by the entity-attribute-value antipattern. Some day, years ago, a guy decided that DDL wasn't sexy, and wanted to develop something "flexible enough" to keep information about people. He ignored the fact that people uses to have at least some basic attributes, as name, date of birth, and the like. Not only that, he put a bunch of (side-effects-ridden) PL/SQL packages on top of that schema. The thing managed to be a key subsystem in which other applications relied on.

Fast forward some years and 20 million rows. The guy isn't at the company anymore, and I have to deal with this. I need to implement some basic searches that right now would require multiple inner joins and just take forever for some cases. Rewriting the whole thing it's not possible, so I want to "pivot" the most important attributes.

I thought that materialized views could be a viable alternative, but I need some guidance, since I have never used them. I would like to get a table like this:

  select
      uid,
       max(case when att = 'NAME' then UPPER(value) end) name,
       max(case when att = 'SURNAME' then UPPER(value) end) surname,
       max(case when att = 'BIRTH' then DATEORNULL(value) end) birth,
     ....,
     count(*) cnt
 from t
 group by uid

as I understand reading Oracle docs, I should be able to create a "REFRESHABLE ON COMMIT" materialized view with MAX() if the query has no where clause.

But can't get it to work. I've tried:

create materialized view log on t WITH SEQUENCE,ROWID,(value) INCLUDING NEW VALUES;

create materialized view t_view
 refresh fast on commit
 as
  select
      uid,
       max(case when att = 'NAME' then UPPER(value) end) name,
       max(case when att = 'SURNAME' then UPPER(value) end) surname,
       max(case when att = 'BIRTH' then DATEORNULL(value) end) birth,
     count(*) cnt
 from t
 group by uid

It works for inserts, but not for updates. I see that is capable of these things:

  REFRESH_COMPLETE                                                             

  REFRESH_FAST                                                                 

  REFRESH_FAST_AFTER_INSERT

but I think I should see also REFRESH_FAST_AFTER_ONETAB_DML. Any ideas?

Update: Output of dbms_mview.explain_mview

REFRESH_COMPLETE             |Y|
REFRESH_FAST                 |Y|
REFRESH_FAST_AFTER_INSERT    |Y|
REFRESH_FAST_AFTER_ONETAB_DML|N|mv uses the MIN or MAX aggregate functions
REFRESH_FAST_AFTER_ANY_DML   |N|see the reason why REFRESH_FAST_AFTER_ONETAB_DML is disabled
REFRESH_FAST_PCT             |N|PCT is not possible on any of the detail tables in the mater
4

1 回答 1

3

The MV_CAPABILITIES_TABLE.MSGTXT is wrong, what you really need to do is replace case with decode.

When I tried this on 11g I got the message CASE expressions present in materialized view. Changing it to use decode fixed it on both 10g and 11g.

于 2012-02-20T04:37:37.900 回答