默认的如果你创建了一个cube cube 里面的数据只有在你手工执行
dbms_cubebuild(<cube_name>) 才会刷新
比如你在前面已经建立好了global 的price_cube 并且执行了第一次dbms_cubebuild(price_cube) 你才能查询到数据 比如执行以下sql:
select * from table(cube_table(price_cube))
where product=ITEM_ENVY STD and time=MONTH_′;
此时输出如下 (注意大小写下划线和空格):
unit_cost unit_price time product
MONTH_ ITEM_ENVY STD
现在我们手工更新price_fact 表的这条数据(price_cube 的实际数据来源)
update price_fact set unit_price=
where month_id= and item_id=ENVY STD;
rows updated
现在重新查看price_cube 的数据你会发现跟刚才的一样 unit_price 还是等于 而不是随着price_fact 表的数据更新到
启用Cube MV 刷新数据的前提条件
如果你希望你的cube 随着实体表的更新而刷新的话(不一定要是同步) 你就需要把cube 设置成按mv 方式来组织 不过首先你需要满足以下几个条件:
所有的dimension 必须至少有一个level 和 hierarchy
所有的dimension 必须使用同一种聚合操作 summinmax 等等
一个cube 的所有属性必须正确的映射到实体表 一个cube 可以有calculated measures 但是不能映射到mv 如果一个cube 的脚本中有高级分析函数也不能映射
dimension 和fact table 之间必须要有约束至少是外键约束 如果你没有定义你可以在启用mv 的时候用Relational Schema Advisor 帮你映射
所有的表上的约束必须同一类型
cube 被压缩了
为了更好的使用query rewrite 你应该创建relational dimension 对象
关于第二点otn 上给的global_schema 的price_cube 的聚合操作就不是同一的sum 操作所以你启用mv 刷新的时候会报错注意根据错误信息调整
关于第三点 calculated measure 支持的分析函数:
除了在第一个文件夹 简单算术 文件夹下的六个(+×/%) 其他都算高级分析函数
关于第四点fact table 和dimension table 之间至少要有外键约束 这应该是建模标准之一如果不是多维数据集 比如g 之前的类型你可以方便的在外键之间建立组合索引 对于g 的cube 类型来说必须需要至少外键约束
关于第六点默认的用awm 创建的cube 里面的是没有指定压缩类型和压缩比率的只有在第一次刷新之后再启用mv 刷新的时候才能选择压缩选项 awm 里面有提示注意参考提示信息
关于第七点最重要 所谓relational dimension 就是我们通过create dimension 创建的对象 而我们之前说的dimension 一般都是指cube dimension 它指的是在analysis workspace 里面的dimension 对象
relational dimension 你可以通过查看dba_dimensions 视图查看 主要用来控制mv query rewrite 的
cube dimension 可以通过查看dba_cube_dimensions 视图查看 另外两个跟aw 相关的视图是dba_cubes 和dba_aws
g 有一些新的跟aw 相关的试图你可以查看
SELECT * FROM dba_objects WHERE object_name LIKE %AW%;
其中包括了dimension 和cube 的元数据dimension 和cube 的统计图信息(analyze 之后收集的) dimension 和cube mv 的元数据 cube 的分区建议和储存建议 具体查看oracle g 的文档
默认的你创建cube 的时候它会创建对应的relational dimension (awm 里面是这样 手工从pl/sql 里面创建没试过) 你可以删除relational dimension cube 里面的dimension 是不会跟着删除的
relational dimension的一些操作
查看dimension 的pl/sql
exec dbms_dimensiondescribe_dimension(globalproduct_dimension);
输出:
DIMENSION GLOBALPRODUCT_DIMENSION LEVEL FAMILY IS GLOBALPRODUCT_DIMFAMILY_ID LEVEL ITEM IS GLOBALPRODUCT_DIMITEM_ID
LEVEL TOTAL IS GLOBALPRODUCT_DIMTOTAL_ID
LEVEL class IS GLOBALPRODUCT_DIMCLASS_ID
HIERARCHY primary ( ITEM CHILD OF
FAMILY CHILD OF
class CHILD OF
TOTAL
)
ATTRIBUTE FAMILY LEVEL FAMILY DETERMINES GLOBALPRODUCT_DIMFAMILY_DSC
ATTRIBUTE ITEM LEVEL ITEM DETERMINES GLOBALPRODUCT_DIMITEM_DSC
ATTRIBUTE TOTAL LEVEL TOTAL DETERMINES GLOBALPRODUCT_DIMTOTAL_DSC
ATTRIBUTE class LEVEL class DETERMINES GLOBALPRODUCT_DIMCLASS_DSC
启用cube mv 刷新
实际启用cube mv 刷新是很简单的 主要是前提条件都满足了 在awm 的cube 里面Materialized Views 选项卡里面点击 Enable Materalized View 选项和 Enable Query Rewrite 选项
刷新模式有Complete Fast Force 其他可选方法还有PCT (Partition Change Tracking) 和Fast Solve;
Complete – 全部删除再全部装载
Fast – 使用mv log 记录变化的记录并且只更新这些记录和对应的聚合记录
Force 默认使用fast 如果fast 不可用才使用complete
Partition Change Tracking: 只刷新部分分区的数据这在awm 里面没有
Fast Solve: 加载所有的原始数据但是只计算新数据的聚合值awm 里面没有
mv 不会计算calculated measures 并且随着mv 的体积增大创建和刷新的速度会变慢(不是呈线性下降)如果你mv 过大你应该考虑分割成几个sub cube 或者去掉一些不用的属性
你选择使用mv 来刷新数据之后oracle 会为每一个dimension 的每个hierarchy 都创建一个mv 并且mv 的名字都是以CB$ 开头 你是不能控制这些mv 的只能控制cube 以下的sql 可以得到所有的cube 对应的mv
启用Query Rewrite
要使用query rewrite 必须满足以下条件:
要有create mv 权限和其他相关对象的权限
在initora 文件中设置QUERY_REWRITE_ENABLED= TRUE 或FORCE 在session 里面也可以
注意awm 里面的检查信息
注意查看Relational Schema Advisor 注意这很重要Relational Schema Advisor 在mv 选项卡的最下面上图中最下面那个灰色的按钮 里面会列出你的schema 不符合query rewrite 的条件 它会给出sql 让你执行注意查看这些sql 以避免query rewrite 失败
你也可能会想要改变约束类型 从enforced trusted norely 到RELY 因为oracle执行计划消耗会更小
alter table price_fact add constraint xxx_constraint PRIMARY KEY (ITEM_ID MONTH_ID UNIT_PRICE UNIT_COST) RELY enable validate ;
刷新MV
刷新时间点上有三种方式:
on demand 等待手工刷新
start next 定时到将来刷新
on commit 每次源表有提交都刷新
推荐的维护mv 刷新还是使用awm 如果是定时的话就使用下面一些pl/sql
exec dbms_cubebuild(PRICE_CUBE); — 这是全刷新
可以一句话包含多个cube 或dimension exec dbms_cubebuild(PRICE_CUBE xxx_CUBE xxx_dimension);
刷新mv:
exec dbms_mviewrefresh(CB$PRODUCT_PRIMARYC);
C 当然是代表complete 这会刷新所有跟这个dimension 的这个hierarchy 有关的mv
或者exec dbms_mviewrefresh(CB$PRICE_CUBEF) 这会以force 方式刷新这个cube 的它对应的mv
你可以说使用以下sql 查看mv 的状态:
select owner||||mview_name cube_mv rewrite_enabled staleness
from all_mviews
where container_name like CB$%;
Staleness 这一栏下有fresh 和stale 两种状态fresh 表示所有数据都已经最新了 stale 表示有新的数据没有刷新但是mv 仍然可用
MV 的一些注意事项
如果query rewrite 没有使用mv 则检查:
query_rewrite_enabled =FORCE
query_rewrite_integrity=stale_tolerated
使用dbms_mviewexplain_rewrite 查看为什么query rewrite 没有成功