今天和用户交流,用户突然问到,TimesTen可否缓存多个Oracle的表,也即将多个表Join的结果缓存?
我们先做几个实验,然后再看有什么解决方法。
先建立基础表和 Materialized View。
CREATE TABLE customer(custId int not null, custName varchar(100) not null, Addr varchar(100), Zip int, Region varchar(10), PRIMARY KEY (custId));
CREATE TABLE bookOrder(orderId int not null, custId int not null, book varchar(100), PRIMARY KEY (orderId), FOREIGN KEY (custId) REFERENCES Customer(custId));
insert into customer values(1, 'tom', 'beijing', 100036, 'china');
insert into customer values(2, 'jerry', 'shanghai', 200031, 'china');
commit;
insert into bookOrder values(100, 1, 'Red and Black');
insert into bookOrder values(200, 2, 'Pride and Judice');
commit;
然后建立同步的物化视图, 可以看到物化视图毕竟不同于普通的View,还是需要空间的。
和View系统的一点是只读。
Command>
CREATE MATERIALIZED VIEW SampleMV AS
SELECT customer.custId, custName, orderId, book
FROM customer, bookOrder
WHERE customer.custId=bookOrder.custId;
2 rows materialized.
Command> desc samplemv;
Materialized view TTHR.SAMPLEMV:
Columns:
CUSTID NUMBER (38) NOT NULL
CUSTNAME VARCHAR2 (100) INLINE NOT NULL
ORDERID NUMBER (38) NOT NULL
BOOK VARCHAR2 (100) INLINE
1 view found.
Command> call ttComputeTabSizes('SAMPLEMV', 1);
Command> tablesize SAMPLEMV
Sizes of ORACLE.SAMPLEMV:
INLINE_ALLOC_BYTES: 69664
NUM_USED_ROWS: 2
NUM_FREE_ROWS: 254
AVG_ROW_LEN: 277
OUT_OF_LINE_BYTES: 0
METADATA_BYTES: 1296
TOTAL_BYTES: 70960
LAST_UPDATED: 2016-07-08 02:01:43.000000
1 table found.
Command> delete from SampleMV;
805: Delete view table directly has not been implemented
The command failed.
测试其实时性:
Command> delete from bookorder where custid = 2;
1 row deleted.
Command> delete from customer where custid = 2;
1 row deleted.
Command> select * from samplemv;
< 1, tom, 100, Red & Black >
1 row found.
Command> delete from bookorder where custid = 1;
1 row deleted.
Command> delete from customer where custid = 1;
1 row deleted.
Command> select * from samplemv;
0 rows found.
接下来创建异步的物化视图
异步的MV虽然实时性不如同步MV,但对系统的性能影响却小得多。数据的同步可以手工,定期(FAST)或是在用户交易提交后更新。
Command> drop Materialized view samplemv;
Command>
CREATE MATERIALIZED VIEW SampleAMV
REFRESH
FAST
NEXT SYSDATE + NUMTODSINTERVAL(1, 'MINUTE')
AS SELECT customer.custId, custName, orderId, book
FROM customer, bookOrder
WHERE customer.custId=bookOrder.custId;
3153: There is no materialized view log on table TTHR.CUSTOMER
The command failed.
建立失败,因为FAST更新需要 materialized view log
If you use the FAST refresh method, the deferred transactions are saved in a materialized view log. Thus, before you create an asynchronous materialized view, you must create a materialized view log for each detail table included in the asynchronous materialized view that uses FAST refresh. Each detail table can have only one materialized view log even if they are used by more than one asynchronous materialized view with FAST refresh. All columns referenced in an asynchronous materialized view must be included in the corresponding asynchronous materialized view log.
以下成功了:
Command> CREATE MATERIALIZED VIEW LOG ON customer WITH PRIMARY KEY (custName);
Command> CREATE MATERIALIZED VIEW LOG ON bookOrder WITH (custId, book);
insert into customer values(1, 'tom', 'beijing', 100036, 'china');
insert into customer values(2, 'jerry', 'shanghai', 200031, 'china');
commit;
insert into bookOrder values(100, 1, 'Red & Black');
insert into bookOrder values(200, 2, 'Pride & Judice');
commit;
Command>
CREATE MATERIALIZED VIEW SampleAMV
REFRESH
FAST
NEXT SYSDATE + NUMTODSINTERVAL(1, 'MINUTE')
AS SELECT customer.custId, custName, orderId, book
FROM customer, bookOrder
WHERE customer.custId=bookOrder.custId;
0 rows materialized.
Command> select * from sampleamv;
< 1, tom, 100, Red & Black >
< 2, jerry, 200, Pride & Judice >
2 rows found.
Command> delete from bookorder;
2 rows deleted.
Command> select * from sampleamv;
< 1, tom, 100, Red & Black >
< 2, jerry, 200, Pride & Judice >
2 rows found.
Command> sleep 60;
Command> select * from sampleamv;
0 rows found.
删除MV和MV log
Command> drop materialized view sampleamv;
Command> drop materialized view log on bookorder;
Command> drop materialized view log on customer;
一句话,只有User Managed 缓存组支持缓存Oracle中的物化视图。
Command>
CREATE USERMANAGED CACHE GROUP "UM_MV"
FROM samplemv(
custId int not null,
custName char(100) not null,
orderId int not null,
book varchar2(100),
PRIMARY KEY(orderId)
);
Warning 5144: The cache group contains a Oracle materialized view, cache operations are restricted.
Command> cachegroups
Cache Group TTHR.UM_MV:
Cache Group Type: User Managed (Restricted)
Autorefresh: No
Aging: No aging defined
Root Table: TTHR.SAMPLEMV
Table Type: Not Propagate
1 cache group found.
Command> load cache group um_mv commit every 256 rows;
2 cache instances affected.
Command> select * from samplemv;
< 1, tom , 100, Red and Black >
< 2, jerry , 200, Pride and Judice >
2 rows found.
Command> load cache group um_mv commit every 256 rows;
0 cache instances affected.
Command> refresh cache group um_mv commit every 256 rows;
2 cache instances affected.
SQL>
insert into customer values(3, 'rose', 'nanjing', 100036, 'china');
commit;
insert into bookOrder values(300, 3, 'You and I');
commit;
CREATE MATERIALIZED VIEW LOG ON customer WITH PRIMARY KEY (custName);
CREATE MATERIALIZED VIEW LOG ON bookOrder WITH (custId, book);
# 和TimesTen不同,Oracle中的物化视图缺省是异步的,因此必须手工刷新
EXEC DBMS_MVIEW.REFRESH('SAMPLEMV', 'F', '', TRUE, FALSE, 0,0,0, FALSE, FALSE);
Command> flush cache group um_mv;
5123: Operation not allowed on restricted cache group UM_MV
The command failed.
# 既然是视图,就只能refereh而不能flush了。
下面的测试验证TimesTen中的物化视图可不可以基于cache table。
CREATE READONLY CACHE GROUP "RO"
AUTOREFRESH MODE INCREMENTAL INTERVAL 5 SECONDS
STATE ON
FROM
"TTHR"."CUSTOMER" (
"CUSTID" NUMBER(38) NOT NULL,
"CUSTNAME" CHAR(100 BYTE) NOT NULL,
"ADDR" CHAR(100 BYTE),
"ZIP" NUMBER(38) ,
"REGION" CHAR(10 BYTE) ,
PRIMARY KEY("CUSTID")
),
"TTHR"."BOOKORDER" (
"ORDERID" NUMBER(38) NOT NULL,
"CUSTID" NUMBER(38) NOT NULL,
"BOOK" VARCHAR2(100 BYTE),
PRIMARY KEY("ORDERID"),
FOREIGN KEY("CUSTID")
REFERENCES "TTHR"."CUSTOMER"("CUSTID")
)
Command> cachegroups;
Cache Group TTHR.RO:
Cache Group Type: Read Only
Autorefresh: Yes
Autorefresh Mode: Incremental
Autorefresh State: On
Autorefresh Interval: 5 Seconds
Autorefresh Status: ok
Aging: No aging defined
Root Table: TTHR.CUSTOMER
Table Type: Read Only
Child Table: TTHR.BOOKORDER
Table Type: Read Only
1 cache group found.
Command> select * from customer;
< 1, tom , beijing , 100036, china >
< 2, jerry , shanghai , 200031, china >
< 3, rose , nanjing , 100036, china >
3 rows found.
Command> select * from bookorder;
< 100, 1, Red and Black >
< 200, 2, Pride and Judice >
< 300, 3, You and I >
3 rows found.
Command> CREATE MATERIALIZED VIEW SampleMV AS
> SELECT customer.custId, custName, orderId, book
> FROM customer, bookOrder
> WHERE customer.custId=bookOrder.custId;
3 rows materialized.
Command> select * from SampleMV;
< 1, tom , 100, Red and Black >
< 2, jerry , 200, Pride and Judice >
< 3, rose , 300, You and I >
3 rows found.
SQL> delete from bookorder where custid = 3;
1 row deleted.
SQL> commit;
Commit complete.
Command> select * from SampleMV;
< 1, tom , 100, Red and Black >
< 2, jerry , 200, Pride and Judice >
2 rows found.
CREATE VIEW SampleV AS
SELECT customer.custId, custName, orderId, book
FROM customer, bookOrder
WHERE customer.custId=bookOrder.custId;
Command> CREATE VIEW SampleV AS
> SELECT customer.custId, custName, orderId, book
> FROM customer, bookOrder
> WHERE customer.custId=bookOrder.custId;
Command> select * from samplev;
< 1, tom , 100, Red and Black >
< 2, jerry , 200, Pride and Judice >
2 rows found.
Command> drop view samplev;
几乎可以说没用。
物化视图一般位于数据仓库的访问层和性能层,就是为了查询加速用的,但有了内存计算后,物化视图基本无用,完全用内存缓存来替代了。
例如Oracle的BI分析一体机Exalytics就是使用TimesTen或12c DBIM缓存数据。
下面这张图也可以说明,有了内存计算后,数据仓库结构的变化: