oracle exchange partition 测试,oracleexchange
Exchange partition提供了一种方式,让你在表与表或分区与分区之间迁移数据,注意不是将表转换成分区或非分区的形式,而仅只是迁移表中数
据(互相迁移),由于其号称是采用了更改数据字典的方式,因此效率最高( 几乎不涉及io操作)。Exchange partition适用于所有分区格式,你可以将数据从分区表迁移到非分区表,也可以从非分区表迁移至分区表。
这就给批量更新分区表的数据提供了一个很不错的思路,这里我便做一次普通表与分区表数据交换的实验。
注意:分区表不能直接与分区表交换所以
如果对换分区表,用普通表过渡
如果对换普通表,用分区表过渡
索引必须是LOCAL INDEX,不能是GLOBAL INDEX
1.创建测试表空间
create tablespace tbs1 datafile '/oracle_data/szdb/tbs1_01.dbf' size 10m autoextend on;
create tablespace tbs2 datafile '/oracle_data/szdb/tbs2_01.dbf' size 10m autoextend on;
2.创建测试表
drop table t_temp purge;
drop table t_part_list purge;
create table t_temp as select 1 id, t.owner,t.OBJECT_NAME,t.OBJECT_ID,t.OBJECT_TYPE from dba_objects t;
create table t_part_list (id number,owner varchar2(20),object_name varchar2(40),object_id number,object_type varchar2(20))
partition by list (id)
(partition p1 values(1) tablespace tbs1,
partition p2 values(2) tablespace tbs2
);
3.查看表数据
SQL> select count(*) from t_part_list;
COUNT(*)
---------
0
SQL> select count(*) from t_temp;
COUNT(*)
----------
80905
4.交换数据
alter table t_part_list exchange partition p1 with table t_temp;
或
alter table t_part_list exchange partition p1 with table t_temp without validation;--不再验证数据有效性
5.查看表数据
SQL> select count(*) from t_part_list;
COUNT(*)
----------
80905
SQL> select count(*) from t_part_list partition(p1);
COUNT(*)
----------
80905
SQL> select count(*) from t_temp;
COUNT(*)
----------
0
6.注意
在将未分区表的数据迁移到分区表中时,可能出现ora-14099的错误,虽然可以用without validation去解决,但是此时进入分区表的数据可能不符合分区规则。
所以without validation一定要慎用。
涉及交换的两表之间表结构必须一致,除非附加with validation子句;
如果是从非分区表向分区表做交换,非分区表中的数据必须符合分区表中指定分区的规则,除非附加without validation子句;
如果从分区表向分区表做交换,被交换的分区的数据必须符合分区规则,除非附加without validation子句;
Global索引或涉及到数据改动了的global索引分区会被置为unusable,除非附加update indexes子句。
提示:一旦附加了without validation子句,则表示不再验证数据有效性,因此指定该子句时务必慎重。
你好,楼上这两个是不对的,partition by是分组的,首先得分组,按照day分组只会还是原值,因为sum的结果是按照分组来做的,运行楼上两个的结果仍然为
1 22 22
2 32 32
3 21 21
4 45 45
5 54 54
6 12 12
7 67 67
若想得到以上结果,首先必须在原始数据添加一列,我们假设为其添加姓名列,使原表变为:
name day sal
zh 1 22
zh 2 32
zh 3 21
zh 4 45
zh 5 54
zh 6 12
zh 7 67
on 1 23
on 2 46
为了看查询效果,我们还添加了另外一个人的名字on
其对应的查询语句应该为:
select day,sal,sum(sal) over(partition by name order by name,day) sumsaltoyesterday from A;
最终显示结果为:
day sal sumsaltoyesterday
1 23 23
2 46 69
1 22 22
2 32 54
3 21 75
4 45 120
5 54 174
6 12 186
7 67 253
其实前两条数据是on的,后面的数据是zh的,要想看出区别,可在结果列中加上姓名
create table test_ta(year number, month number, area varchar2(20), region varchar2(20), business varchar2(20), income number);
select *
from (select year,
month,
area,
dense_rank() over(partition by year, month order by income desc) rank
from (select t.year, t.month, t.area, sum(income) income
from test_ta t
group by t.year, t.month, t.area))
where rank = 1
-- 最内层子查询:统计每个月份,每个大区的总收入
-- 第二层子查询:对每个月份,每个大区进行分组,按照总收入倒序排序,给出序号(此处同一月份总收入相同的,序号相同,看你自己的需求,看是取一条还是都取,取一条,则把dense_rank()替换成row_number())
-- 最外层查询:查询排序序号为1的记录,即每月总收入最多的大区
希望对你有帮助