Oracle 12c Materialized Views 只查看最新记录

Oracle12 Materialized Views only latest records

假设您有 table 位车主 (car_owners) :
car_id
person_id
registration_date ...

每次有人买车时,都会在其中插入一条记录 table。

现在我想创建一个物化视图,它只保存每辆车的最新注册,即当插入一条记录时,物化视图用新记录更新这辆车的记录(如果它存在)来自基地 table。 物化视图每辆车只保留一条记录。

我试过这样的东西

create materialized view newest_owner
build immediately
refresh force on commit
select *
  from car_owners c
 where c.registration_date = (
         select max(cc.registration_date)
           from car_owners cc
          where cc.car_id = c.car_id
       );

实体化视图似乎不喜欢子选择。

关于如何执行此操作或如何以其他方式实现此操作,您有任何提示吗? 我现在有另一个解决方案,使用触发器更新单独的 table 以保存最新值,但我希望物化视图可以解决问题。

谢谢。

为此,您可能必须使用嵌套的物化视图:

create table car_owners 
(pk_col number primary key
,car_id  number 
,person_id number 
,registration_date date
);
truncate table car_owners;
insert into car_owners
select rownum
      ,trunc(dbms_random.value(1,1000)) car_id
      ,mod(rownum,100000) person_id
      ,(sysdate-dbms_random.value(1,3000)) registration_date
from dual 
connect by rownum <= 1000000;
commit;
exec dbms_stats.gather_Table_stats(null,'car_owners')

create materialized view log on car_owners with sequence, rowid
(car_id, registration_date) including new values;

create materialized view latest_registration
refresh fast on commit enable query rewrite 
as
select c.car_id
    ,max(c.registration_date) max_registration_date
from car_owners c
group by c.car_id
/

create materialized view log on latest_registration with sequence, rowid
(car_id, max_registration_date) including new values;

create materialized view newest_owner
refresh fast on commit enable query rewrite 
as
select c.rowid row_id,cl.rowid cl_rowid, c.pk_col, c.car_id, c.person_id, c.registration_date
  from car_owners c
  join latest_registration  cl
   on   c.registration_date = cl.max_registration_date
  and   c.car_id = cl.car_id
/
select * from newest_owner where car_id = 25;

ROW_ID             CL_ROWID               PK_COL     CAR_ID  PERSON_ID REGISTRAT
------------------ ------------------ ---------- ---------- ---------- ---------
AAAUreAAMAAD/IxABS AAAUriAAMAAD+TNACE     644158         25      44158 09-APR-22

insert into car_owners values (1000001, 25,-1,sysdate);
commit;
select * from newest_owner where car_id = 25;

ROW_ID             CL_ROWID               PK_COL     CAR_ID  PERSON_ID REGISTRAT
------------------ ------------------ ---------- ---------- ---------- ---------
AAAUreAAMAAD/pLAB1 AAAUriAAMAAD+TNACE    1000001         25         -1 22-APR-22

explain plan for 
select c.rowid row_id,cl.rowid cl_rowid, c.pk_col, c.car_id, c.person_id, c.registration_date
  from car_owners c
  join latest_registration  cl
   on   c.registration_date = cl.max_registration_date
  and   c.car_id = cl.car_id
/
select * from dbms_xplan.display();

---------------------------------------------------------------------------------------------
| Id  | Operation                    | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |              |   999 | 41958 |     3   (0)| 00:00:01 |
|   1 |  MAT_VIEW REWRITE ACCESS FULL| NEWEST_OWNER |   999 | 41958 |     3   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------

阅读文档:https://docs.oracle.com/en/database/oracle/oracle-database/21/dwhsg/basic-materialized-views.html#GUID-E087FDD0-B08C-4878-BBA9-DE56A705835E https://docs.oracle.com/en/database/oracle/oracle-database/21/dwhsg/basic-materialized-views.html#GUID-179C8C8A-585B-49E6-8970-09396DB53DE3有些限制会减慢您的刷新速度(例如删除)。