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