作为一种优化策略,我们正在研究如何使用Oracle Partition Metadata来识别哪些分区在过去24小时内插入/更新了行。我们只想处理更改的分区。
有人知道分区是否存在此类元数据吗?
谢谢, Dáire
答案 0 :(得分:1)
如果您想使用元数据执行此操作,而不是构建自己的监控(使用触发器或时间戳列或物化视图或其他内容),那么我认为答案是排序
如果您为分区表启用监控,请执行以下操作:
ALTER TABLE my_partitioned_tab MONITORING;
,然后Oracle将跟踪针对表和每个单独分区的更新次数。此信息在DBA_TAB_MODIFICATIONS
中可见。
但是,该视图中的TIMESTAMP
列是数据刷新时的时间戳,数据仅按需刷新,或者在收集统计信息时或实例关闭时按时刷新,或者经常& #34; (因发布而异)。
按需刷新按如下方式进行:
BEGIN DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO; END;
刷新后,您可以看到DBA_TAB_MODIFICATIONS
中的数据:
select partition_name, timestamp
from dba_tab_modifications
where table_name = 'MY_PARTITIONED_TAB';
但是,无论如何,在Oracle 12c中,TIMESTAMP
将是刷新数据的时间,而不是修改发生的时间。 (此表的Oracle的文档在这一点上是不准确/误导的。)
所以,最重要的是,如果您能够可靠地清除监控,例如10分钟,您应该能够近似地估算过去24小时内(+/- 10分钟)修改了哪些分区。 / p>
答案 1 :(得分:0)
您可以使用分区更改跟踪(PCT) 识别修改后的分区。
您唯一需要考虑的是在分区表上设置包含您的prtition键或PMARKER的非常简单的物化视图。 (请参阅其他requirement以启用PCT)
PCT功能跟踪MV的基表(即您的分区表),并将修改后的分区标记为STALE
(即必须在MV中刷新的分区)。您可以使用字典视图USER_MVIEW_DETAIL_PARTITION
示例强>
设置分区表和PCT MV
CREATE TABLE tp
("NAME" VARCHAR2(30 BYTE),
"SAMPLE_MINUTE" DATE
)
PARTITION BY RANGE (SAMPLE_MINUTE)
INTERVAL (NUMTODSINTERVAL(1,'DAY'))
(
PARTITION part_01 values LESS THAN (TO_DATE('01-03-2017','DD-MM-YYYY'))
);
insert into tp (NAME, SAMPLE_MINUTE) values ('xx', to_date('01012017','ddmmyyyy'));
commit;
CREATE MATERIALIZED VIEW TPM
refresh complete on demand with primary key
AS
select DBMS_MVIEW.PMARKER(rowid) pm, count(*) cnt
from tp
group by DBMS_MVIEW.PMARKER(rowid);
现在,让我们检查MV元数据
select DETAIL_PARTITION_NAME, DETAIL_PARTITION_POSITION, FRESHNESS
from USER_MVIEW_DETAIL_PARTITION where MVIEW_NAME = 'TPM';
DETAIL_PARTITION_NAME DETAIL_PARTITION_POSITION FRESHNESS
------------------------------ ------------------------- ---------
PART_01 1 FRESH
所以,这是最初的统计数据,我们有一个分区,这是新鲜的。让我们在同一个分区中添加其他记录..
insert into tp (NAME, SAMPLE_MINUTE) values ('yy', to_date('01012017','ddmmyyyy'));
commit;
select DETAIL_PARTITION_NAME, DETAIL_PARTITION_POSITION, FRESHNESS
from USER_MVIEW_DETAIL_PARTITION where MVIEW_NAME = 'TPM';
DETAIL_PARTITION_NAME DETAIL_PARTITION_POSITION FRESHNESS
------------------------------ ------------------------- ---------
PART_01 1 STALE
正如预期的那样,分区现在已经过时了。所以现在我们在其他分区中添加一条新记录(注意我使用间隔分区,因此分区将自动创建)
insert into tp (NAME, SAMPLE_MINUTE) values ('yy', to_date('03032017','ddmmyyyy'));
commit;
select DETAIL_PARTITION_NAME, DETAIL_PARTITION_POSITION, FRESHNESS
from USER_MVIEW_DETAIL_PARTITION where MVIEW_NAME = 'TPM';
DETAIL_PARTITION_NAME DETAIL_PARTITION_POSITION FRESHNESS
------------------------------ ------------------------- ---------
PART_01 1 STALE
SYS_P9341 2 STALE
还可以,现在我们有两个过时的分区
如果要重置状态(即在运行处理更改的分区的作业之后),只需刷新物化视图,所有分区将再次FRESH
exec dbms_mview.REFRESH( LIST => 'TPM', method => 'P', atomic_refresh => FALSE);
select DETAIL_PARTITION_NAME, DETAIL_PARTITION_POSITION, FRESHNESS
from USER_MVIEW_DETAIL_PARTITION where MVIEW_NAME = 'TPM';
DETAIL_PARTITION_NAME DETAIL_PARTITION_POSITION FRESHNESS
------------------------------ ------------------------- ---------
PART_01 1 FRESH
SYS_P9341 2 FRESH
请注意,您正在使用PCT刷新MV(方法=' P'),因此只会重新标记陈旧分区。
刷新MV会重置更改状态;您可以根据需要完全控制 - 每24小时一次或在执行处理更改的作业后按需控制。