Oracle 物化视图:分区策略
Oracle Materialized views: partition strategy
我有一个按年 (char)、月 (char) 和其他 3 个维度组织的摘要物化视图,然后是许多度量。我的数据从2013年到现在还在不断增加。
由于基础事实 table 很大(500+M 行每年递增 100+M)我正在考虑对 table 和 MV 进行分区以便仅刷新最近12个月的MV。
经过多次阅读,我应该按范围(每个月)对事实 table 进行分区,按月对 MV 进行分区,然后按年对其进行细分。
我知道分区策略对性能至关重要,所以我想问问是否有人有更好的解决方案或者我制定的那个是最优的。
谢谢!
MV分区代码示例:
CREATE MATERIALIZED VIEW my_mv
PARTITION BY LIST (month) SUBPARTITION BY LIST (year)
( PARTITION p01 VALUES ('01')
( SUBPARTITION p_0117 VALUES ('2017')
, SUBPARTITION p_0116 VALUES ('2016')
, SUBPARTITION p_0115 VALUES ('2015')
, SUBPARTITION p_0114 VALUES ('2014')
, SUBPARTITION p_0113 VALUES ('2013')
)
, PARTITION p02 VALUES ('02')
( SUBPARTITION p_0217 VALUES ('2017')
, SUBPARTITION p_0216 VALUES ('2016')
, SUBPARTITION p_0215 VALUES ('2015')
, SUBPARTITION p_0214 VALUES ('2014')
, SUBPARTITION p_0213 VALUES ('2013')
)
...
, PARTITION p12 VALUES ('12')
( SUBPARTITION p_1217 VALUES ('2017')
, SUBPARTITION p_1216 VALUES ('2016')
, SUBPARTITION p_1215 VALUES ('2015')
, SUBPARTITION p_1214 VALUES ('2014')
, SUBPARTITION p_1213 VALUES ('2013')
)
)
AS
SELECT
...
FROM
...
;
为什么不按月进行简单分区?按月分区,按年分区,没有任何意义。删除旧分区是不可能的,一般来说维护起来会很困难。
SELECT
...
TO_TIMESTAMP(year||month, 'YYYYMM') AS PARTITION_KEY,
...
然后给你MView:
PARTITION BY RANGE (PARTITION_KEY) INTERVAL (INTERVAL '1' MONTH)
这也使您免于任何分区维护。
关于性能,它在很大程度上取决于您 运行 对它的主要查询。在分区 table 上的性能很容易比在非分区 table 上的性能差。如果您的主要查询不 select 某些日期范围,那么日期分区是矛盾的(就性能而言)。
我有一个按年 (char)、月 (char) 和其他 3 个维度组织的摘要物化视图,然后是许多度量。我的数据从2013年到现在还在不断增加。
由于基础事实 table 很大(500+M 行每年递增 100+M)我正在考虑对 table 和 MV 进行分区以便仅刷新最近12个月的MV。
经过多次阅读,我应该按范围(每个月)对事实 table 进行分区,按月对 MV 进行分区,然后按年对其进行细分。
我知道分区策略对性能至关重要,所以我想问问是否有人有更好的解决方案或者我制定的那个是最优的。
谢谢!
MV分区代码示例:
CREATE MATERIALIZED VIEW my_mv
PARTITION BY LIST (month) SUBPARTITION BY LIST (year)
( PARTITION p01 VALUES ('01')
( SUBPARTITION p_0117 VALUES ('2017')
, SUBPARTITION p_0116 VALUES ('2016')
, SUBPARTITION p_0115 VALUES ('2015')
, SUBPARTITION p_0114 VALUES ('2014')
, SUBPARTITION p_0113 VALUES ('2013')
)
, PARTITION p02 VALUES ('02')
( SUBPARTITION p_0217 VALUES ('2017')
, SUBPARTITION p_0216 VALUES ('2016')
, SUBPARTITION p_0215 VALUES ('2015')
, SUBPARTITION p_0214 VALUES ('2014')
, SUBPARTITION p_0213 VALUES ('2013')
)
...
, PARTITION p12 VALUES ('12')
( SUBPARTITION p_1217 VALUES ('2017')
, SUBPARTITION p_1216 VALUES ('2016')
, SUBPARTITION p_1215 VALUES ('2015')
, SUBPARTITION p_1214 VALUES ('2014')
, SUBPARTITION p_1213 VALUES ('2013')
)
)
AS
SELECT
...
FROM
...
;
为什么不按月进行简单分区?按月分区,按年分区,没有任何意义。删除旧分区是不可能的,一般来说维护起来会很困难。
SELECT
...
TO_TIMESTAMP(year||month, 'YYYYMM') AS PARTITION_KEY,
...
然后给你MView:
PARTITION BY RANGE (PARTITION_KEY) INTERVAL (INTERVAL '1' MONTH)
这也使您免于任何分区维护。
关于性能,它在很大程度上取决于您 运行 对它的主要查询。在分区 table 上的性能很容易比在非分区 table 上的性能差。如果您的主要查询不 select 某些日期范围,那么日期分区是矛盾的(就性能而言)。