我正在尝试将非分区数据与分区数据交换。我已经完成了以下步骤。
[创建了一个新表TEMP_TABLE,其分区的TEMP_TABLE_1范围为日期('1-09-2019')。而且我用过
ALTER TABLE TEMP_TABLE
EXCHANGE PARTITION TEMP_TABLE_1
WITH TABLE ORG_TABLE
WITHOUT VALIDATION
UPDATE GLOBAL INDEXES;
通过此操作,我的表数据与分区交换,新表可以看到包含数据的分区。但是现在的问题是,当我尝试时,数据包含日期大于1-09-2019的行
select count(*) from TEMP_TABLE where date > '1-09-2019';
尽管有直到今天的日期数据,但其仍为0。
如果我尝试分割此分区
ALTER TABLE TEMP_TABLE SPLIT PARTITION TEMP_TABLE_1 INTO (PARTITION
TEMP_TABLE_2 values LESS THAN (TO_DATE('01-OCT-2019 00:00:00', 'DD-MON-
YYYY HH24:MI:SS')), PARTITION TEMP_TABLE_1) UPDATE GLOBAL INDEXES
PARALLEL 4;
其抛出分区不能沿指定的上限分割。
如何获取超过我提供的日期范围的数据。
当您未经验证就交换数据时(可能是为了提高性能),Oracle将不会验证所插入数据的分区键列的值是否与要插入该数据的分区的分区范围条件相匹配。
--partitioned table
create table mytabp(n date)
partition by range(n)
interval(numtodsinterval(1, 'DAY'))
(partition p0 values less than (to_date('20190901','yyyymmdd')));
--nonpartitioned table to hold the data outside partition range
create table temp_mytab(n date);
insert into temp_mytab values(to_date('20191001','yyyymmdd'));
--exchanging without validation
alter table mytabp exchange partition p0 with table temp_mytab without validation;
--Data exists
select count(1) from mytabp;--1
由于在下面的查询中对分区进行了修剪,因此在分区中搜索记录,该分区必须根据定义保存此数据。由于记录存在于错误的分区中,因此不会返回数据。
select count(1) from mytabp where n > to_date('20190901','yyyymmdd');--0
通过在分区列上应用TRUNC,Oracle可以选择扫描所有分区。因此下面的SQL产生记录。对我而言,在Exadata上的Oracle 12cR1上,此SQL用TRUNC的后续执行扫描了记录所在的确切分区,而不扫描所有分区。我在解释计划的PARTITON_START和PARTITION_STOP列中对此进行了检查。
select count(1) from mytabp where trunc(n) > to_date('20190901','yyyymmdd');--1
根据设计,将数据放置在不正确的分区上是不好的。请在执行未经验证的交换之前验证或过滤正确的数据。