

range单字段分区:
-- 范围分区示例
drop table range_part_tab purge;
--注意,此分区为范围分区
--例子1
create table range_part_tab (id number,deal_date date,area_code number,nbr number,contents varchar2(4000))
partition by range (deal_date)
(
partition p_201301 values less than (TO_DATE('2013-02-01', 'YYYY-MM-DD')),
partition p_201302 values less than (TO_DATE('2013-03-01', 'YYYY-MM-DD')),
partition p_201303 values less than (TO_DATE('2013-04-01', 'YYYY-MM-DD')),
partition p_201304 values less than (TO_DATE('2013-05-01', 'YYYY-MM-DD')),
partition p_201305 values less than (TO_DATE('2013-06-01', 'YYYY-MM-DD')),
partition p_201306 values less than (TO_DATE('2013-07-01', 'YYYY-MM-DD')),
partition p_201307 values less than (TO_DATE('2013-08-01', 'YYYY-MM-DD')),
partition p_201308 values less than (TO_DATE('2013-09-01', 'YYYY-MM-DD')),
partition p_201309 values less than (TO_DATE('2013-10-01', 'YYYY-MM-DD')),
partition p_201310 values less than (TO_DATE('2013-11-01', 'YYYY-MM-DD')),
partition p_201311 values less than (TO_DATE('2013-12-01', 'YYYY-MM-DD')),
partition p_201312 values less than (TO_DATE('2014-01-01', 'YYYY-MM-DD')),
partition p_201401 values less than (TO_DATE('2014-02-01', 'YYYY-MM-DD')),
partition p_201402 values less than (TO_DATE('2014-03-01', 'YYYY-MM-DD')),
partition p_max values less than (maxvalue)
)
;
--以下是插入2013年一整年日期随机数和表示福建地区号含义(591到599)的随机数记录,共有10万条,如下:
insert into range_part_tab (id,deal_date,area_code,nbr,contents)
select rownum,
to_date( to_char(sysdate-365,'J')+TRUNC(DBMS_RANDOM.VALUE(0,365)),'J'),
ceil(dbms_random.value(591,599)),
ceil(dbms_random.value(18900000001,18999999999)),
rpad('*',400,'*')
from dual
connect by rownum <= 100000;
commit;
--以下是插入2014年一整年日期随机数和表示福建地区号含义(591到599)的随机数记录,共有10万条,如下:
insert into range_part_tab (id,deal_date,area_code,nbr,contents)
select rownum,
to_date( to_char(sysdate,'J')+TRUNC(DBMS_RANDOM.VALUE(0,365)),'J'),
ceil(dbms_random.value(591,599)),
ceil(dbms_random.value(18900000001,18999999999)),
rpad('*',400,'*')
from dual
connect by rownum <= 100000;
commit;
--全局索引
create index idx_part_id on range_part_tab (id) ;
--局部索引
create index idx_part_nbr on range_part_tab (nbr) local;
--统计信息系统一般会自动收集,这只是首次建成表后需要操作一下,以方便测试
exec dbms_stats.gather_table_stats(ownname => 'LJB',tabname => 'RANGE_PART_TAB',estimate_percent => 10,method_opt=> 'for all indexed columns',cascade=>TRUE) ;
select min(deal_date),max(deal_date) from range_part_tab;
select count(*) from range_part_tab partition (p_201301);
select count(*) from range_part_tab partition (p_201302);
select count(*) from range_part_tab partition (p_201303);
select count(*) from range_part_tab partition (p_201304);
select count(*) from range_part_tab partition (p_201305);
select count(*) from range_part_tab partition (p_201306);
select count(*) from range_part_tab partition (p_201307);
select count(*) from range_part_tab partition (p_201308);
select count(*) from range_part_tab partition (p_201309);
select count(*) from range_part_tab partition (p_201310);
select count(*) from range_part_tab partition (p_201311);
select count(*) from range_part_tab partition (p_201312);
select count(*) from range_part_tab partition (p_max);
--查看当前用户下分区表及对应索引的相关信息
--(表及索引多大,多少个分区,在哪一个列建了分区,表及索引的分区的类型是什么,有无子分区)
set linesize 366
col partitioning_type format a10
col subpartitioning_type format a10
col partition_count format 99999
col column_name format a20
col object_type format a10
col blevel format 9
col num_rows format 99999999
col leaf_blocks format 999999
col column_position format 9
col partition_name format a28
col segment_type format a20
col index_name format a28
col table_name format a30
col last_analyzed format date
col status format a8
---01 该表是否是分区表,分区表的分区类型是什么,是否有子分区,分区总数有多少
select partitioning_type,
subpartitioning_type,
partition_count
from user_part_tables
where table_name ='RANGE_PART_TAB';
PARTITIONI SUBPARTITI PARTITION_COUNT
---------- ---------- ---------------
RANGE NONE 15
--02 该分区表在哪一列上建分区,有无多列联合建分区
select column_name,
object_type,
column_position
from user_part_key_columns
where name ='RANGE_PART_TAB';
COLUMN_NAME OBJECT_TYP COLUMN_POSITION
-------------------- ---------- ---------------
DEAL_DATE TABLE 1
--03 该分区表有多大?
select sum(bytes) / 1024 / 1024
from user_segments
where segment_name ='RANGE_PART_TAB';
SUM(BYTES)/1024/1024
--------------------
110
--04 该分区表各分区分别有多大,各个分区名是什么。
select partition_name,
segment_type,
bytes
from user_segments
where segment_name ='RANGE_PART_TAB';
PARTITION_NAME SEGMENT_TYPE BYTES
---------------------------- -------------------- ----------
P_201301 TABLE PARTITION 9437184
P_201302 TABLE PARTITION 4194304
P_201303 TABLE PARTITION 5242880
P_201304 TABLE PARTITION 5242880
P_201305 TABLE PARTITION 5242880
P_201306 TABLE PARTITION 5242880
P_201307 TABLE PARTITION 5242880
P_201308 TABLE PARTITION 5242880
P_201309 TABLE PARTITION 5242880
P_201310 TABLE PARTITION 5242880
P_201311 TABLE PARTITION 5242880
P_201312 TABLE PARTITION 5242880
P_201401 TABLE PARTITION 5242880
P_201402 TABLE PARTITION 4194304
P_MAX TABLE PARTITION 39845888
已选择15行。
--05 该分区表的统计信息收集情况
select table_name,
partition_name,
last_analyzed,
partition_position,
num_rows
from user_tab_statistics t
where table_name ='RANGE_PART_TAB';
TABLE_NAME PARTITION_NAME LAST_ANALYZED PARTITION_POSITION NUM_ROWS
------------------------------ ---------------------------- -------------- ------------------ ---------
RANGE_PART_TAB 01-12月-13 200080
RANGE_PART_TAB P_201301 01-12月-13 1 17010
RANGE_PART_TAB P_201302 01-12月-13 2 7855
RANGE_PART_TAB P_201303 01-12月-13 3 8378
RANGE_PART_TAB P_201304 01-12月-13 4 8132
RANGE_PART_TAB P_201305 01-12月-13 5 8430
RANGE_PART_TAB P_201306 01-12月-13 6 8317
RANGE_PART_TAB P_201307 01-12月-13 7 8571
RANGE_PART_TAB P_201308 01-12月-13 8 8312
RANGE_PART_TAB P_201309 01-12月-13 9 8327
RANGE_PART_TAB P_201310 01-12月-13 10 8469
RANGE_PART_TAB P_201311 01-12月-13 11 8218
RANGE_PART_TAB P_201312 01-12月-13 12 8387
RANGE_PART_TAB P_201401 01-12月-13 13 8434
RANGE_PART_TAB P_201402 01-12月-13 14 7663
RANGE_PART_TAB P_MAX 01-12月-13 15 76150
--06 查该分区表有无索引,分别什么类型,全局索引是否失效,此外还可看统计信息收集情况。
--(其中status值为N/A 表示分区索引,分区索引是否失效是在user_ind_partitions中查看)
select table_name,
index_name,
last_analyzed,
blevel,
num_rows,
leaf_blocks,
distinct_keys,
status
from user_indexes
where table_name ='RANGE_PART_TAB';
TABLE_NAME INDEX_NAME LAST_ANALYZED BLEVEL NUM_ROWS LEAF_BLOCKS DISTINCT_KEYS STATUS
------------------------------ ---------------------------- -------------- ------ --------- ----------- ------------- --------
RANGE_PART_TAB IDX_PART_NBR 01-12月-13 1 200000 536 199774 N/A
RANGE_PART_TAB IDX_PART_ID 01-12月-13 1 200000 555 100000 VALID
--07 该分区表在哪些列上建了索引
select index_name,
column_name,
column_position
from user_ind_columns
where table_name = 'RANGE_PART_TAB';
INDEX_NAME COLUMN_NAME COLUMN_POSITION
---------------------------- -------------------- ---------------
IDX_PART_ID ID 1
IDX_PART_NBR NBR 1
--08 该分区表上的各索引分别有多大。
select segment_name,segment_type,sum(bytes)/1024/1024
from user_segments
where segment_name in
(select index_name
from user_indexes
where table_name ='RANGE_PART_TAB')
group by segment_name,segment_type ;
SEGMENT_NAME SEGMENT_TYPE SUM(BYTES)/1024/1024
------------------------------------------ --------------------
IDX_PART_ID INDEX 5
IDX_PART_NBR INDEX PARTITION 5.6875
--09 该分区表的索引段的分配情况
select segment_name
partition_name,
segment_type,
bytes
from user_segments
where segment_name in
(select index_name
from user_indexes
where table_name ='RANGE_PART_TAB');
PARTITION_NAME SEGMENT_TYPE BYTES
---------------------------- -------------------- ----------
IDX_PART_ID INDEX 5242880
IDX_PART_NBR INDEX PARTITION 458752
IDX_PART_NBR INDEX PARTITION 262144
IDX_PART_NBR INDEX PARTITION 262144
IDX_PART_NBR INDEX PARTITION 262144
IDX_PART_NBR INDEX PARTITION 262144
IDX_PART_NBR INDEX PARTITION 262144
IDX_PART_NBR INDEX PARTITION 262144
IDX_PART_NBR INDEX PARTITION 262144
IDX_PART_NBR INDEX PARTITION 262144
IDX_PART_NBR INDEX PARTITION 262144
IDX_PART_NBR INDEX PARTITION 262144
IDX_PART_NBR INDEX PARTITION 262144
IDX_PART_NBR INDEX PARTITION 262144
IDX_PART_NBR INDEX PARTITION 262144
IDX_PART_NBR INDEX PARTITION 2097152
已选择16行。
--10 分区索引相关信息及统计信息、是否失效查看。
select t2.table_name,
t1.index_name,
t1.partition_name,
t1.last_analyzed,
t1.blevel,
t1.num_rows,
t1.leaf_blocks,
t1.status
from user_ind_partitions t1, user_indexes t2
where t1.index_name = t2.index_name
and t2.table_name='RANGE_PART_TAB';
TABLE_NAME INDEX_NAME PARTITION_NAME LAST_ANALYZED BLEVEL NUM_ROWS LEAF_BLOCKS STATUS
-------------------------------------------------------------- ------ --------- ----------- -------
RANGE_PART_TAB IDX_PART_NBR P_201301 01-12月-13 1 16883 45 USABLE
RANGE_PART_TAB IDX_PART_NBR P_201302 01-12月-13 1 7876 21 USABLE
RANGE_PART_TAB IDX_PART_NBR P_201303 01-12月-13 1 8448 23 USABLE
RANGE_PART_TAB IDX_PART_NBR P_201304 01-12月-13 1 8295 22 USABLE
RANGE_PART_TAB IDX_PART_NBR P_201305 01-12月-13 1 8388 23 USABLE
RANGE_PART_TAB IDX_PART_NBR P_201306 01-12月-13 1 8234 22 USABLE
RANGE_PART_TAB IDX_PART_NBR P_201307 01-12月-13 1 8540 23 USABLE
RANGE_PART_TAB IDX_PART_NBR P_201308 01-12月-13 1 8312 22 USABLE
RANGE_PART_TAB IDX_PART_NBR P_201309 01-12月-13 1 8350 23 USABLE
RANGE_PART_TAB IDX_PART_NBR P_201310 01-12月-13 1 8496 23 USABLE
RANGE_PART_TAB IDX_PART_NBR P_201311 01-12月-13 1 8178 22 USABLE
RANGE_PART_TAB IDX_PART_NBR P_201312 01-12月-13 1 8425 23 USABLE
RANGE_PART_TAB IDX_PART_NBR P_201401 01-12月-13 1 8477 23 USABLE
RANGE_PART_TAB IDX_PART_NBR P_201402 01-12月-13 1 7628 21 USABLE
RANGE_PART_TAB IDX_PART_NBR P_MAX 01-12月-13 1 75470 200 USABLE
联合字段分区:
-- 范围分区示例
drop table range_part_mult_col_tab purge;
--注意,此分区为联合字段的范围分区
create table range_part_mult_col_tab (id number,deal_date date,area_code number,nbr number,contents varchar2(4000))
partition by range (area_code,deal_date)
(
partition p_591_201301 values less than (591,TO_DATE('2013-02-01', 'YYYY-MM-DD')),
partition p_591_201302 values less than (591,TO_DATE('2013-03-01', 'YYYY-MM-DD')),
partition p_591_201303 values less than (591,TO_DATE('2013-04-01', 'YYYY-MM-DD')),
partition p_591_201304 values less than (591,TO_DATE('2013-05-01', 'YYYY-MM-DD')),
partition p_591_201305 values less than (591,TO_DATE('2013-06-01', 'YYYY-MM-DD')),
partition p_591_201306 values less than (591,TO_DATE('2013-07-01', 'YYYY-MM-DD')),
partition p_591_201307 values less than (591,TO_DATE('2013-08-01', 'YYYY-MM-DD')),
partition p_591_201308 values less than (591,TO_DATE('2013-09-01', 'YYYY-MM-DD')),
partition p_591_201309 values less than (591,TO_DATE('2013-10-01', 'YYYY-MM-DD')),
partition p_591_201310 values less than (591,TO_DATE('2013-11-01', 'YYYY-MM-DD')),
partition p_591_201311 values less than (591,TO_DATE('2013-12-01', 'YYYY-MM-DD')),
partition p_591_201312 values less than (591,TO_DATE('2014-01-01', 'YYYY-MM-DD')),
partition p_591_201401 values less than (591,TO_DATE('2014-02-01', 'YYYY-MM-DD')),
partition p_591_201402 values less than (591,TO_DATE('2014-03-01', 'YYYY-MM-DD')),
partition p_591_max values less than (591,maxvalue),
partition p_592_201301 values less than (592,TO_DATE('2013-02-01', 'YYYY-MM-DD')),
partition p_592_201302 values less than (592,TO_DATE('2013-03-01', 'YYYY-MM-DD')),
partition p_592_201303 values less than (592,TO_DATE('2013-04-01', 'YYYY-MM-DD')),
partition p_592_201304 values less than (592,TO_DATE('2013-05-01', 'YYYY-MM-DD')),
partition p_592_201305 values less than (592,TO_DATE('2013-06-01', 'YYYY-MM-DD')),
partition p_592_201306 values less than (592,TO_DATE('2013-07-01', 'YYYY-MM-DD')),
partition p_592_201307 values less than (592,TO_DATE('2013-08-01', 'YYYY-MM-DD')),
partition p_592_201308 values less than (592,TO_DATE('2013-09-01', 'YYYY-MM-DD')),
partition p_592_201309 values less than (592,TO_DATE('2013-10-01', 'YYYY-MM-DD')),
partition p_592_201310 values less than (592,TO_DATE('2013-11-01', 'YYYY-MM-DD')),
partition p_592_201311 values less than (592,TO_DATE('2013-12-01', 'YYYY-MM-DD')),
partition p_592_201312 values less than (592,TO_DATE('2014-01-01', 'YYYY-MM-DD')),
partition p_592_201401 values less than (592,TO_DATE('2014-02-01', 'YYYY-MM-DD')),
partition p_592_201402 values less than (592,TO_DATE('2014-03-01', 'YYYY-MM-DD')),
partition p_592_max values less than (592,maxvalue),
partition p_593_201301 values less than (593,TO_DATE('2013-02-01', 'YYYY-MM-DD')),
partition p_593_201302 values less than (593,TO_DATE('2013-03-01', 'YYYY-MM-DD')),
partition p_593_201303 values less than (593,TO_DATE('2013-04-01', 'YYYY-MM-DD')),
partition p_593_201304 values less than (593,TO_DATE('2013-05-01', 'YYYY-MM-DD')),
partition p_593_201305 values less than (593,TO_DATE('2013-06-01', 'YYYY-MM-DD')),
partition p_593_201306 values less than (593,TO_DATE('2013-07-01', 'YYYY-MM-DD')),
partition p_593_201307 values less than (593,TO_DATE('2013-08-01', 'YYYY-MM-DD')),
partition p_593_201308 values less than (593,TO_DATE('2013-09-01', 'YYYY-MM-DD')),
partition p_593_201309 values less than (593,TO_DATE('2013-10-01', 'YYYY-MM-DD')),
partition p_593_201310 values less than (593,TO_DATE('2013-11-01', 'YYYY-MM-DD')),
partition p_593_201311 values less than (593,TO_DATE('2013-12-01', 'YYYY-MM-DD')),
partition p_593_201312 values less than (593,TO_DATE('2014-01-01', 'YYYY-MM-DD')),
partition p_593_201401 values less than (593,TO_DATE('2014-02-01', 'YYYY-MM-DD')),
partition p_593_201402 values less than (593,TO_DATE('2014-03-01', 'YYYY-MM-DD')),
partition p_593_max values less than (593,maxvalue)
)
;
--以下是插入2013年一整年日期随机数和表示福州,厦门,宁德三地的地区号含义(591到593)的随机数记录,共有10万条,如下:
insert into range_part_mult_col_tab (id,deal_date,area_code,nbr,contents)
select rownum,
to_date( to_char(sysdate-365,'J')+TRUNC(DBMS_RANDOM.VALUE(0,365)),'J'),
ceil(dbms_random.value(591,593)),
ceil(dbms_random.value(18900000001,18999999999)),
rpad('*',400,'*')
from dual
connect by rownum <= 100000;
commit;
select count(*) from range_part_mult_col_tab partition (p_591_201301);
select count(*) from range_part_mult_col_tab partition (p_591_201302);
select count(*) from range_part_mult_col_tab partition (p_591_201303);
select count(*) from range_part_mult_col_tab partition (p_591_201304);
select count(*) from range_part_mult_col_tab partition (p_591_201305);
select count(*) from range_part_mult_col_tab partition (p_591_201306);
select count(*) from range_part_mult_col_tab partition (p_591_201307);
select count(*) from range_part_mult_col_tab partition (p_591_201308);
select count(*) from range_part_mult_col_tab partition (p_591_201309);
select count(*) from range_part_mult_col_tab partition (p_591_201310);
select count(*) from range_part_mult_col_tab partition (p_591_201311);
select count(*) from range_part_mult_col_tab partition (p_591_201312);
select count(*) from range_part_mult_col_tab partition (p_591_max);
select count(*) from range_part_mult_col_tab partition (p_592_201301);
select count(*) from range_part_mult_col_tab partition (p_592_201302);
select count(*) from range_part_mult_col_tab partition (p_592_201303);
select count(*) from range_part_mult_col_tab partition (p_592_201304);
select count(*) from range_part_mult_col_tab partition (p_592_201305);
select count(*) from range_part_mult_col_tab partition (p_592_201306);
select count(*) from range_part_mult_col_tab partition (p_592_201307);
select count(*) from range_part_mult_col_tab partition (p_592_201308);
select count(*) from range_part_mult_col_tab partition (p_592_201309);
select count(*) from range_part_mult_col_tab partition (p_592_201310);
select count(*) from range_part_mult_col_tab partition (p_592_201311);
select count(*) from range_part_mult_col_tab partition (p_592_201312);
select count(*) from range_part_mult_col_tab partition (p_592_max);
select count(*) from range_part_mult_col_tab partition (p_593_201301);
select count(*) from range_part_mult_col_tab partition (p_593_201302);
select count(*) from range_part_mult_col_tab partition (p_593_201303);
select count(*) from range_part_mult_col_tab partition (p_593_201304);
select count(*) from range_part_mult_col_tab partition (p_593_201305);
select count(*) from range_part_mult_col_tab partition (p_593_201306);
select count(*) from range_part_mult_col_tab partition (p_593_201307);
select count(*) from range_part_mult_col_tab partition (p_593_201308);
select count(*) from range_part_mult_col_tab partition (p_593_201309);
select count(*) from range_part_mult_col_tab partition (p_593_201310);
select count(*) from range_part_mult_col_tab partition (p_593_201311);
select count(*) from range_part_mult_col_tab partition (p_593_201312);
select count(*) from range_part_mult_col_tab partition (p_593_max);
create index idx_part_mul_id on range_part_mult_col_tab (id) ;
create index idx_part_mul_nbr on range_part_mult_col_tab (nbr) local;
--统计信息系统一般会自动收集,这只是首次建成表后需要操作一下,以方便测试
exec dbms_stats.gather_table_stats(ownname => 'LJB',tabname => 'RANGE_PART_MULT_COL_TAB',estimate_percent => 10,method_opt=> 'for all indexed columns',cascade=>TRUE) ;
--查看当前用户下分区表及对应索引的相关信息
--(表及索引多大,多少个分区,在哪一个列建了分区,表及索引的分区的类型是什么,有无子分区)
set linesize 366
col partitioning_type format a10
col subpartitioning_type format a10
col partition_count format 99999
col column_name format a20
col object_type format a10
col blevel format 9
col num_rows format 99999999
col leaf_blocks format 999999
col column_position format 9
col partition_name format a28
col segment_type format a20
col index_name format a28
col table_name format a30
col last_analyzed format date
col status format a8
---该表是否是分区表,分区表的分区类型是什么,是否有子分区,分区总数有多少
select partitioning_type,
subpartitioning_type,
partition_count
from user_part_tables
where table_name ='RANGE_PART_MULT_COL_TAB';
--该分区表在哪一列上建分区,有无多列联合建分区
select column_name,
object_type,
column_position
from user_part_key_columns
where name ='RANGE_PART_MULT_COL_TAB';
--该分区表有多大?
select sum(bytes) / 1024 / 1024
from user_segments
where segment_name ='RANGE_PART_MULT_COL_TAB';
--该分区表各分区分别有多大,各个分区名是什么。
select partition_name,
segment_type,
bytes
from user_segments
where segment_name ='RANGE_PART_MULT_COL_TAB';
--该分区表的统计信息收集情况
select table_name,
partition_name,
last_analyzed,
partition_position,
num_rows
from user_tab_statistics t
where table_name ='RANGE_PART_MULT_COL_TAB';
--查该分区表有无索引,分别什么类型,全局索引是否失效,此外还可看统计信息收集情况。
--(其中status值为N/A 表示分区索引,分区索引是否失效是在user_ind_partitions中查看)
select table_name,
index_name,
last_analyzed,
blevel,
num_rows,
leaf_blocks,
distinct_keys,
status
from user_indexes
where table_name ='RANGE_PART_MULT_COL_TAB';
--该分区表在哪些列上建了索引
select index_name,
column_name,
column_position
from user_ind_columns
where table_name = 'RANGE_PART_MULT_COL_TAB';
--该分区表上的各索引分别有多大。
select segment_name,segment_type,sum(bytes)/1024/1024
from user_segments
where segment_name in
(select index_name
from user_indexes
where table_name ='RANGE_PART_MULT_COL_TAB')
group by segment_name,segment_type ;
--该分区表的索引段的分配情况
select segment_name
partition_name,
segment_type,
bytes
from user_segments
where segment_name in
(select index_name
from user_indexes
where table_name ='RANGE_PART_MULT_COL_TAB');
--分区索引相关信息及统计信息、是否失效查看。
select t2.table_name,
t1.index_name,
t1.partition_name,
t1.last_analyzed,
t1.blevel,
t1.num_rows,
t1.leaf_blocks,
t1.status
from user_ind_partitions t1, user_indexes t2
where t1.index_name = t2.index_name
and t2.table_name='RANGE_PART_MULT_COL_TAB';
列表分区示例:
--列表分区示例
drop table list_part_tab purge;
--注意,此分区为列表分区
create table list_part_tab (id number,deal_date date,area_code number,nbr number,contents varchar2(4000))
partition by list (area_code)
(
partition p_591 values (591),
partition p_592 values (592),
partition p_593 values (593),
partition p_594 values (594),
partition p_595 values (595),
partition p_596 values (596),
partition p_597 values (597),
partition p_598 values (598),
partition p_599 values (599),
partition p_other values (DEFAULT)
)
;
--以下是插入2013年一整年日期随机数和表示福建地区号含义(591到599)的随机数记录,共有10万条,如下:
insert into list_part_tab (id,deal_date,area_code,nbr,contents)
select rownum,
to_date( to_char(sysdate-365,'J')+TRUNC(DBMS_RANDOM.VALUE(0,365)),'J'),
ceil(dbms_random.value(590,599)),
ceil(dbms_random.value(18900000001,18999999999)),
rpad('*',400,'*')
from dual
connect by rownum <= 100000;
commit;
select count(*) from list_part_tab partition(p_591);
select count(*) from list_part_tab partition(p_592);
select count(*) from list_part_tab partition(p_593);
select count(*) from list_part_tab partition(p_594);
select count(*) from list_part_tab partition(p_595);
select count(*) from list_part_tab partition(p_596);
select count(*) from list_part_tab partition(p_597);
select count(*) from list_part_tab partition(p_598);
select count(*) from list_part_tab partition(p_599);
select count(*) from list_part_tab partition(p_other);
create index idx_list_part_id on list_part_tab (id) ;
create index idx_list_part_nbr on list_part_tab (nbr) local;
--统计信息系统一般会自动收集,这只是首次建成表后需要操作一下,以方便测试
exec dbms_stats.gather_table_stats(ownname => 'LJB',tabname => 'LIST_PART_TAB',estimate_percent => 10,method_opt=> 'for all indexed columns',cascade=>TRUE) ;
--查看当前用户下分区表及对应索引的相关信息
--(表及索引多大,多少个分区,在哪一个列建了分区,表及索引的分区的类型是什么,有无子分区)
set linesize 366
col partitioning_type format a10
col subpartitioning_type format a10
col partition_count format 99999
col column_name format a20
col object_type format a10
col blevel format 9
col num_rows format 99999999
col leaf_blocks format 999999
col column_position format 9
col partition_name format a28
col segment_type format a20
col index_name format a28
col table_name format a30
col last_analyzed format date
col status format a8
---该表是否是分区表,分区表的分区类型是什么,是否有子分区,分区总数有多少
select partitioning_type,
subpartitioning_type,
partition_count
from user_part_tables
where table_name ='LIST_PART_TAB';
--该分区表在哪一列上建分区,有无多列联合建分区
select column_name,
object_type,
column_position
from user_part_key_columns
where name ='LIST_PART_TAB';
--该分区表有多大?
select sum(bytes) / 1024 / 1024
from user_segments
where segment_name ='LIST_PART_TAB';
--该分区表各分区分别有多大,各个分区名是什么。
select partition_name,
segment_type,
bytes
from user_segments
where segment_name ='LIST_PART_TAB';
--该分区表的统计信息收集情况
select table_name,
partition_name,
last_analyzed,
partition_position,
num_rows
from user_tab_statistics t
where table_name ='LIST_PART_TAB';
--查该分区表有无索引,分别什么类型,全局索引是否失效,此外还可看统计信息收集情况。
--(其中status值为N/A 表示分区索引,分区索引是否失效是在user_ind_partitions中查看)
select table_name,
index_name,
last_analyzed,
blevel,
num_rows,
leaf_blocks,
distinct_keys,
status
from user_indexes
where table_name ='LIST_PART_TAB';
--该分区表在哪些列上建了索引
select index_name,
column_name,
column_position
from user_ind_columns
where table_name = 'LIST_PART_TAB';
--该分区表上的各索引分别有多大。
select segment_name,segment_type,sum(bytes)/1024/1024
from user_segments
where segment_name in
(select index_name
from user_indexes
where table_name ='LIST_PART_TAB')
group by segment_name,segment_type ;
--该分区表的索引段的分配情况
select segment_name
partition_name,
segment_type,
bytes
from user_segments
where segment_name in
(select index_name
from user_indexes
where table_name ='LIST_PART_TAB');
--分区索引相关信息及统计信息、是否失效查看。
select t2.table_name,
t1.index_name,
t1.partition_name,
t1.last_analyzed,
t1.blevel,
t1.num_rows,
t1.leaf_blocks,
t1.status
from user_ind_partitions t1, user_indexes t2
where t1.index_name = t2.index_name
and t2.table_name='LIST_PART_TAB';
hash单字段分区:
--散列分区示例
drop table hash_part_tab purge;
--注意,此分区HASH分区
create table hash_part_tab (id number,deal_date date,area_code number,nbr number,contents varchar2(4000))
partition by hash (deal_date)
PARTITIONS 12
;
--以下是插入2013年一整年日期随机数和表示福建地区号含义(591到599)的随机数记录,共有10万条,如下:
insert into hash_part_tab(id,deal_date,area_code,nbr,contents)
select rownum,
to_date( to_char(sysdate-365,'J')+TRUNC(DBMS_RANDOM.VALUE(0,365)),'J'),
ceil(dbms_random.value(590,599)),
ceil(dbms_random.value(18900000001,18999999999)),
rpad('*',400,'*')
from dual
connect by rownum <= 100000;
commit;
--以下分区名是通过数据字典user_segments的partition_name查出来的,详见后面说明。
select partition_name,
segment_type,
bytes,
'select count(*) from hash_part_tab partition('||partition_name||');'
from user_segments
where segment_name ='HASH_PART_TAB';
create index idx_hash_part_id on hash_part_tab (id) ;
create index idx_hash_part_nbr on hash_part_tab (nbr) local;
--统计信息系统一般会自动收集,这只是首次建成表后需要操作一下,以方便测试
exec dbms_stats.gather_table_stats(ownname => 'LJB',tabname => 'HASH_PART_TAB',estimate_percent => 10,method_opt=> 'for all indexed columns',cascade=>TRUE) ;
--查看当前用户下分区表及对应索引的相关信息
--(表及索引多大,多少个分区,在哪一个列建了分区,表及索引的分区的类型是什么,有无子分区)
set linesize 366
col partitioning_type format a10
col subpartitioning_type format a10
col partition_count format 99999
col column_name format a20
col object_type format a10
col blevel format 9
col num_rows format 99999999
col leaf_blocks format 999999
col column_position format 9
col partition_name format a28
col segment_type format a20
col index_name format a28
col table_name format a30
col last_analyzed format date
col status format a8
---该表是否是分区表,分区表的分区类型是什么,是否有子分区,分区总数有多少
select partitioning_type,
subpartitioning_type,
partition_count
from user_part_tables
where table_name ='HASH_PART_TAB';
--该分区表在哪一列上建分区,有无多列联合建分区
select column_name,
object_type,
column_position
from user_part_key_columns
where name ='HASH_PART_TAB';
--该分区表有多大?
select sum(bytes) / 1024 / 1024
from user_segments
where segment_name ='HASH_PART_TAB';
--该分区表各分区分别有多大,各个分区名是什么。
select partition_name,
segment_type,
bytes
from user_segments
where segment_name ='HASH_PART_TAB';
--该分区表的统计信息收集情况
select table_name,
partition_name,
last_analyzed,
partition_position,
num_rows
from user_tab_statistics t
where table_name ='HASH_PART_TAB';
--查该分区表有无索引,分别什么类型,全局索引是否失效,此外还可看统计信息收集情况。
--(其中status值为N/A 表示分区索引,分区索引是否失效是在user_ind_partitions中查看)
select table_name,
index_name,
last_analyzed,
blevel,
num_rows,
leaf_blocks,
distinct_keys,
status
from user_indexes
where table_name ='HASH_PART_TAB';
--该分区表在哪些列上建了索引
select index_name,
column_name,
column_position
from user_ind_columns
where table_name = 'HASH_PART_TAB';
--该分区表上的各索引分别有多大。
select segment_name,segment_type,sum(bytes)/1024/1024
from user_segments
where segment_name in
(select index_name
from user_indexes
where table_name ='HASH_PART_TAB')
group by segment_name,segment_type ;
--该分区表的索引段的分配情况
select segment_name
partition_name,
segment_type,
bytes
from user_segments
where segment_name in
(select index_name
from user_indexes
where table_name ='HASH_PART_TAB');
--分区索引相关信息及统计信息、是否失效查看。
select t2.table_name,
t1.index_name,
t1.partition_name,
t1.last_analyzed,
t1.blevel,
t1.num_rows,
t1.leaf_blocks,
t1.status
from user_ind_partitions t1, user_indexes t2
where t1.index_name = t2.index_name
and t2.table_name='HASH_PART_TAB';
组合分区:
--组合分区示例
drop table range_list_part_tab purge;
--注意,此分区为范围分区
create table range_list_part_tab (id number,deal_date date,area_code number,nbr number,contents varchar2(4000))
partition by range (deal_date)
subpartition by list (area_code)
subpartition TEMPLATE
(subpartition p_591 values (591),
subpartition p_592 values (592),
subpartition p_593 values (593),
subpartition p_594 values (594),
subpartition p_595 values (595),
subpartition p_596 values (596),
subpartition p_597 values (597),
subpartition p_598 values (598),
subpartition p_599 values (599),
subpartition p_other values (DEFAULT))
( partition p_201301 values less than (TO_DATE('2013-02-01', 'YYYY-MM-DD')),
partition p_201302 values less than (TO_DATE('2013-03-01', 'YYYY-MM-DD')),
partition p_201303 values less than (TO_DATE('2013-04-01', 'YYYY-MM-DD')),
partition p_201304 values less than (TO_DATE('2013-05-01', 'YYYY-MM-DD')),
partition p_201305 values less than (TO_DATE('2013-06-01', 'YYYY-MM-DD')),
partition p_201306 values less than (TO_DATE('2013-07-01', 'YYYY-MM-DD')),
partition p_201307 values less than (TO_DATE('2013-08-01', 'YYYY-MM-DD')),
partition p_201308 values less than (TO_DATE('2013-09-01', 'YYYY-MM-DD')),
partition p_201309 values less than (TO_DATE('2013-10-01', 'YYYY-MM-DD')),
partition p_201310 values less than (TO_DATE('2013-11-01', 'YYYY-MM-DD')),
partition p_201311 values less than (TO_DATE('2013-12-01', 'YYYY-MM-DD')),
partition p_201312 values less than (TO_DATE('2014-01-01', 'YYYY-MM-DD')),
partition p_201401 values less than (TO_DATE('2014-02-01', 'YYYY-MM-DD')),
partition p_201402 values less than (TO_DATE('2014-03-01', 'YYYY-MM-DD')),
partition p_max values less than (maxvalue))
;
--以下是插入2013年一整年日期随机数和表示福建地区号含义(591到599)的随机数记录,共有10万条,如下:
insert into range_list_part_tab(id,deal_date,area_code,nbr,contents)
select rownum,
to_date( to_char(sysdate-365,'J')+TRUNC(DBMS_RANDOM.VALUE(0,365)),'J'),
ceil(dbms_random.value(590,599)),
ceil(dbms_random.value(18900000001,18999999999)),
rpad('*',400,'*')
from dual
connect by rownum <= 100000;
commit;
select count(*) from range_list_part_tab partition (p_591);
select count(*) from range_list_part_tab partition (p_201302);
select count(*) from range_list_part_tab partition (p_201303);
select count(*) from range_list_part_tab partition (p_201304);
select count(*) from range_list_part_tab partition (p_201305);
select count(*) from range_list_part_tab partition (p_201306);
select count(*) from range_list_part_tab partition (p_201307);
select count(*) from range_list_part_tab partition (p_201308);
select count(*) from range_list_part_tab partition (p_201309);
select count(*) from range_list_part_tab partition (p_201310);
select count(*) from range_list_part_tab partition (p_201311);
select count(*) from range_list_part_tab partition (p_201312);
select count(*) from range_list_part_tab partition (p_max);
--注意,模板的形式,子分区名是被自动命名了,系统自动组合在一起,如P_201301_P_591
select count(*) from range_list_part_tab subpartition(P_201301_P_591);
create index idx_ran_list_part_id on range_list_part_tab (id) ;
create index idx_ran_list_part_nbr on range_list_part_tab (nbr) local;
--统计信息系统一般会自动收集,这只是首次建成表后需要操作一下,以方便测试
exec dbms_stats.gather_table_stats(ownname => 'LJB',tabname => 'RANGE_LIST_PART_TAB',estimate_percent => 10,method_opt=> 'for all indexed columns',cascade=>TRUE) ;
--查看当前用户下分区表及对应索引的相关信息
--(表及索引多大,多少个分区,在哪一个列建了分区,表及索引的分区的类型是什么,有无子分区)
set linesize 366
col partitioning_type format a10
col subpartitioning_type format a10
col partition_count format 99999
col column_name format a20
col object_type format a10
col blevel format 9
col num_rows format 99999999
col leaf_blocks format 999999
col column_position format 9
col partition_name format a28
col segment_type format a20
col index_name format a28
col table_name format a30
col last_analyzed format date
col status format a8
---该表是否是分区表,分区表的分区类型是什么,是否有子分区,分区总数有多少
select partitioning_type,
subpartitioning_type,
partition_count
from user_part_tables
where table_name ='RANGE_LIST_PART_TAB';
--该分区表在哪一列上建分区,有无多列联合建分区
select column_name,
object_type,
column_position
from user_part_key_columns
where name ='RANGE_LIST_PART_TAB';
--该分区表有多大?
select sum(bytes) / 1024 / 1024
from user_segments
where segment_name ='RANGE_LIST_PART_TAB';
--该分区表各分区分别有多大,各个分区名是什么。
select partition_name,
segment_type,
bytes
from user_segments
where segment_name ='RANGE_LIST_PART_TAB';
--该分区表的统计信息收集情况
select table_name,
partition_name,
last_analyzed,
partition_position,
num_rows
from user_tab_statistics t
where table_name ='RANGE_LIST_PART_TAB';
--查该分区表有无索引,分别什么类型,全局索引是否失效,此外还可看统计信息收集情况。
--(其中status值为N/A 表示分区索引,分区索引是否失效是在user_ind_partitions中查看)
select table_name,
index_name,
last_analyzed,
blevel,
num_rows,
leaf_blocks,
distinct_keys,
status
from user_indexes
where table_name ='RANGE_LIST_PART_TAB';
--该分区表在哪些列上建了索引
select index_name,
column_name,
column_position
from user_ind_columns
where table_name = 'RANGE_LIST_PART_TAB';
--该分区表上的各索引分别有多大。
select segment_name,segment_type,sum(bytes)/1024/1024
from user_segments
where segment_name in
(select index_name
from user_indexes
where table_name ='RANGE_LIST_PART_TAB')
group by segment_name,segment_type ;
--该分区表的索引段的分配情况
select segment_name
partition_name,
segment_type,
bytes
from user_segments
where segment_name in
(select index_name
from user_indexes
where table_name ='RANGE_LIST_PART_TAB');
--分区索引相关信息及统计信息、是否失效查看。
select t2.table_name,
t1.index_name,
t1.partition_name,
t1.last_analyzed,
t1.blevel,
t1.num_rows,
t1.leaf_blocks,
t1.status
from user_ind_partitions t1, user_indexes t2
where t1.index_name = t2.index_name
and t2.table_name='RANGE_LIST_PART_TAB';
分区表的优势:减少访问路径.
--分区原理分析之普通表构造与数据插入
drop table norm_tab purge;
create table norm_tab (id number,deal_date date,area_code number,nbr number,contents varchar2(4000));
insert into norm_tab(id,deal_date,area_code,nbr,contents)
select rownum,
to_date( to_char(sysdate-365,'J')+TRUNC(DBMS_RANDOM.VALUE(0,365)),'J'),
ceil(dbms_random.value(590,599)),
ceil(dbms_random.value(18900000001,18999999999)),
rpad('*',400,'*')
from dual
connect by rownum <= 100000;
commit;
--分区原理分析之分区表构造与数据插入
drop table range_part_tab purge;
create table range_part_tab (id number,deal_date date,area_code number,nbr number,contents varchar2(4000))
partition by range (deal_date)
(
partition p_201301 values less than (TO_DATE('2013-02-01', 'YYYY-MM-DD')),
partition p_201302 values less than (TO_DATE('2013-03-01', 'YYYY-MM-DD')),
partition p_201303 values less than (TO_DATE('2013-04-01', 'YYYY-MM-DD')),
partition p_201304 values less than (TO_DATE('2013-05-01', 'YYYY-MM-DD')),
partition p_201305 values less than (TO_DATE('2013-06-01', 'YYYY-MM-DD')),
partition p_201306 values less than (TO_DATE('2013-07-01', 'YYYY-MM-DD')),
partition p_201307 values less than (TO_DATE('2013-08-01', 'YYYY-MM-DD')),
partition p_201308 values less than (TO_DATE('2013-09-01', 'YYYY-MM-DD')),
partition p_201309 values less than (TO_DATE('2013-10-01', 'YYYY-MM-DD')),
partition p_201310 values less than (TO_DATE('2013-11-01', 'YYYY-MM-DD')),
partition p_201311 values less than (TO_DATE('2013-12-01', 'YYYY-MM-DD')),
partition p_201312 values less than (TO_DATE('2014-01-01', 'YYYY-MM-DD')),
partition p_201401 values less than (TO_DATE('2014-02-01', 'YYYY-MM-DD')),
partition p_201402 values less than (TO_DATE('2014-03-01', 'YYYY-MM-DD')),
partition p_max values less than (maxvalue)
)
;
--以下是插入2013年一整年日期随机数和表示福建地区号含义(591到599)的随机数记录,共有10万条,如下:
insert into range_part_tab (id,deal_date,area_code,nbr,contents)
select rownum,
to_date( to_char(sysdate-365,'J')+TRUNC(DBMS_RANDOM.VALUE(0,365)),'J'),
ceil(dbms_random.value(591,599)),
ceil(dbms_random.value(18900000001,18999999999)),
rpad('*',400,'*')
from dual
connect by rownum <= 100000;
commit;
--分区原理分析之普通表与分区表在段分配上的差异
SET LINESIZE 666
set pagesize 5000
column segment_name format a20
column partition_name format a20
column segment_type format a20
select segment_name,
partition_name,
segment_type,
bytes / 1024 / 1024 "字节数(M)",
tablespace_name
from user_segments
where segment_name IN('RANGE_PART_TAB','NORM_TAB');
--观察范围分区表的分区消除带来的性能优势
set linesize 1000
set autotrace traceonly
set timing on
select *
from range_part_tab
where deal_date >= TO_DATE('2013-08-04', 'YYYY-MM-DD')
and deal_date <= TO_DATE('2013-08-07', 'YYYY-MM-DD');
执行计划
---------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
---------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 958 | 1917K| 171 (1)| 00:00:03 | | |
| 1 | PARTITION RANGE SINGLE| | 958 | 1917K| 171 (1)| 00:00:03 | 8 | 8 |
|* 2 | TABLE ACCESS FULL | RANGE_PART_TAB | 958 | 1917K| 171 (1)| 00:00:03 | 8 | 8 |
---------------------------------------------------------------------------------------------------------
统计信息
----------------------------------------------------------
0 recursive calls
0 db block gets
657 consistent gets
0 physical reads
0 redo size
42053 bytes sent via SQL*Net to client
1240 bytes received via SQL*Net from client
77 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1136 rows processed
--比较相同语句,普通表无法用到DEAL_DATE条件进行分区消除的情况
select *
from norm_tab
where deal_date >= TO_DATE('2013-08-04', 'YYYY-MM-DD')
and deal_date <= TO_DATE('2013-08-07', 'YYYY-MM-DD');
执行计划
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 599 | 1199K| 1709 (1)| 00:00:21 |
|* 1 | TABLE ACCESS FULL| NORM_TAB | 599 | 1199K| 1709 (1)| 00:00:21 |
------------------------------------------------------------------------------
统计信息
----------------------------------------------------------
0 recursive calls
0 db block gets
6373 consistent gets
0 physical reads
0 redo size
42222 bytes sent via SQL*Net to client
1240 bytes received via SQL*Net from client
77 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1137 rows processed
操作方便(truncate):
--操作会导致全局索引失效(要考虑including indexes 或者重建索引)
---关于分区表的truncate分区
--分区表的truncate
connect ljb/ljb
drop table part_tab_trunc purge;
create table part_tab_trunc (id int,col2 int,col3 int,contents varchar2(4000))
partition by range (id)
(
partition p1 values less than (10000),
partition p2 values less than (20000),
partition p3 values less than (maxvalue)
)
;
insert into part_tab_trunc select rownum ,rownum+1,rownum+2, rpad('*',400,'*') from dual connect by rownum <=50000;
commit;
--truncate 分区前
select count(*) from part_tab_trunc partition(p1);
COUNT(*)
---------
9999
alter table part_tab_trunc truncate partition p1 ;
--truncate 分区后
select count(*) from part_tab_trunc partition(p1);
COUNT(*)
---------
0
操作方便(drop):
--操作会导致全局索引失效(要考虑including indexes 或者重建索引),
--分区表的drop
sqlplus ljb/ljb
drop table part_tab_drop purge;
create table part_tab_drop (id int,col2 int ,col3 int,contents varchar2(4000))
partition by range (id)
(
partition p1 values less than (10000),
partition p2 values less than (20000),
partition p3 values less than (maxvalue)
)
;
insert into part_tab_drop select rownum ,rownum+1,rownum+2,rpad('*',400,'*') from dual connect by rownum <=50000;
commit;
--drop 分区前
select partition_name, segment_type, bytes
from user_segments
where segment_name ='PART_TAB_DROP';
PARTITION_NAME SEGMENT_TYPE BYTES
------------------------------ ------------------ ----------
P1 TABLE PARTITION 5242880
P2 TABLE PARTITION 5242880
P3 TABLE PARTITION 15728640
alter table part_tab_drop drop partition p1 ;
--drop 分区后
select partition_name, segment_type, bytes
from user_segments
where segment_name ='PART_TAB_DROP';
PARTITION_NAME SEGMENT_TYPE BYTES
------------------------------ ------------------ ----------
P2 TABLE PARTITION 5242880
P3 TABLE PARTITION 15728640
操作方便(split)
---分区表的SPLIT
drop table part_tab_split purge;
create table part_tab_split (id int,col2 int ,col3 int ,contents varchar2(4000))
partition by range (id)
(
partition p1 values less than (10000),
partition p2 values less than (20000),
partition p_max values less than (maxvalue)
)
;
insert into part_tab_split select rownum ,rownum+1,rownum+2,rpad('*',400,'*') from dual connect by rownum <=90000;
commit;
--split 分区前
select partition_name, segment_type, bytes
from user_segments
where segment_name ='PART_TAB_SPLIT';
PARTITION_NAME SEGMENT_TYPE BYTES
------------------------------ ------------------ ----------
P1 TABLE PARTITION 5242880
P2 TABLE PARTITION 5242880
P_MAX TABLE PARTITION 34603008
已选择3行。
alter table part_tab_split SPLIT PARTITION P_MAX at (30000) into (PARTITION p3 ,PARTITION P_MAX);
alter table part_tab_split SPLIT PARTITION P_MAX at (40000) into (PARTITION p4 ,PARTITION P_MAX);
alter table part_tab_split SPLIT PARTITION P_MAX at (50000) into (PARTITION p5 ,PARTITION P_MAX);
alter table part_tab_split SPLIT PARTITION P_MAX at (60000) into (PARTITION p6 ,PARTITION P_MAX);
alter table part_tab_split SPLIT PARTITION P_MAX at (70000) into (PARTITION p7 ,PARTITION P_MAX);
--split 分区后
select partition_name, segment_type, bytes
from user_segments
where segment_name ='PART_TAB_SPLIT';
PARTITION_NAME SEGMENT_TYPE BYTES
------------------------------ ------------------ ----------
P1 TABLE PARTITION 5242880
P2 TABLE PARTITION 5242880
P3 TABLE PARTITION 5242880
P4 TABLE PARTITION 5242880
P5 TABLE PARTITION 5242880
P6 TABLE PARTITION 5242880
P7 TABLE PARTITION 5242880
P_MAX TABLE PARTITION 10485760
已选择8行。
操作方便add:
drop table part_tab_add purge;
create table part_tab_add (id int,col2 int,col3 int,contents varchar2(4000))
partition by range (id)
(
partition p1 values less than (10000),
partition p2 values less than (20000),
partition p3 values less than (30000),
partition p4 values less than (40000),
partition p5 values less than (50000),
partition p_max values less than (maxvalue)
)
;
insert into part_tab_add select rownum ,rownum+1,rownum+2,rpad('*',400,'*') from dual connect by rownum <=45000;
commit;
--add 分区前
select partition_name, segment_type, bytes
from user_segments
where segment_name ='PART_TAB_ADD';
PARTITION_NAME SEGMENT_TYPE BYTES
------------------------------ ------------------ ----------
P1 TABLE PARTITION 5242880
P2 TABLE PARTITION 5242880
P3 TABLE PARTITION 5242880
P4 TABLE PARTITION 5242880
P5 TABLE PARTITION 3145728
P_MAX TABLE PARTITION 65536
已选择6行。
--注意:必须要把默认分区去掉,再add分区,再增加默认分区,这里要担心丢数据!
alter table part_tab_add drop partition p_max;
alter table part_tab_add add PARTITION p6 values less than (60000);
alter table part_tab_add add PARTITION p_max values less than (maxvalue);
--add 分区后
select partition_name, segment_type, bytes
from user_segments
where segment_name ='PART_TAB_ADD';
PARTITION_NAME SEGMENT_TYPE BYTES
------------------------------ ------------------ ----------
P1 TABLE PARTITION 5242880
P2 TABLE PARTITION 5242880
P3 TABLE PARTITION 5242880
P4 TABLE PARTITION 5242880
P5 TABLE PARTITION 3145728
P6 TABLE PARTITION 65536
P_MAX TABLE PARTITION 65536
已选择7行。
操作方便(exchange):
--操作会导致全局索引失效(要考虑including indexes 或者重建索引),
--分区表的exchange
drop table part_tab_exch purge;
create table part_tab_exch (id int,col2 int,col3 int,contents varchar2(4000))
partition by range (id)
(
partition p1 values less than (10000),
partition p2 values less than (20000),
partition p3 values less than (30000),
partition p4 values less than (40000),
partition p5 values less than (50000),
partition p_max values less than (maxvalue)
)
;
insert into part_tab_exch select rownum ,rownum+1,rownum+2, rpad('*',400,'*') from dual connect by rownum <=60000;
commit;
create index idx_part_exch_col2 on part_tab_exch(col2) local;
create index idx_part_exch_col3 on part_tab_exch (col3);
--分区表的EXCHANGE(某分区和普通表之间的数据进行交换)
drop table normal_tab purge;
create table normal_tab (id int,col2 int,col3 int,contents varchar2(4000));
create index idx_norm_col2 on normal_tab (col2);
--交换前数据情况
select count(*) from normal_tab;
COUNT(*)
----------
0
select count(*) from part_tab partition(p1);
COUNT(*)
----------
999
--其中including indexes 可选,为了保证全局索引不要失效
alter table part_tab_exch exchange partition p1 with table normal_tab including indexes update global indexes;
--交换后数据情况
select count(*) from normal_tab;
COUNT(*)
----------
999
select count(*) from part_tab_exch partition(p1);
COUNT(*)
----------
0
---分区表的分区数据转移后会更改ROWID
set autotrace off
drop table part_tab_rowid purge;
create table part_tab_rowid (id int,col2 int,col3 int,contents varchar2(4000))
partition by range (id)
(
partition p1 values less than (10),
partition p2 values less than (20),
partition p_max values less than (maxvalue)
)
;
insert into part_tab_rowid select rownum ,rownum+1,rownum+2,rpad('*',400,'*') from dual connect by rownum <=30;
commit;
select t.id,t.rowid from part_tab_rowid partition (p1) t;
ID ROWID
---------- ------------------
1 AAAZdQAAGAAATxjAAA
2 AAAZdQAAGAAATxjAAB
3 AAAZdQAAGAAATxjAAC
4 AAAZdQAAGAAATxjAAD
5 AAAZdQAAGAAATxjAAE
6 AAAZdQAAGAAATxjAAF
7 AAAZdQAAGAAATxjAAG
8 AAAZdQAAGAAATxjAAH
9 AAAZdQAAGAAATxjAAI
已选择9行。
select t.id,t.rowid from part_tab_rowid partition (p2) t;
ID ROWID
---------- ------------------
10 AAAZdRAAGAAATxrAAA
11 AAAZdRAAGAAATxrAAB
12 AAAZdRAAGAAATxrAAC
13 AAAZdRAAGAAATxrAAD
14 AAAZdRAAGAAATxrAAE
15 AAAZdRAAGAAATxrAAF
16 AAAZdRAAGAAATxrAAG
17 AAAZdRAAGAAATxrAAH
18 AAAZdRAAGAAATxrAAI
19 AAAZdRAAGAAATxrAAJ
已选择10行。
select dbms_rowid.rowid_object('AAAZdQAAGAAATxjAAA') data_object_id#,
dbms_rowid.rowid_relative_fno('AAAZdQAAGAAATxjAAA') rfile#,
dbms_rowid.rowid_block_number('AAAZdQAAGAAATxjAAA') block#,
dbms_rowid.rowid_row_number('AAAZdQAAGAAATxjAAA') row# from dual;
DATA_OBJECT_ID# RFILE# BLOCK# ROW#
--------------- ---------- ---------- ----------
104272 6 80995 0
--以下这个enable row movement必须操作,否则会出现ORA-014402:更新分区关键字列导致分区更改
alter table part_tab_rowid enable row movement;
update part_tab_rowid set id=12 where id=1;
commit;
select t.id,t.rowid from part_tab_rowid partition(p1) t;
ID ROWID
---------- ------------------
2 AAAZdQAAGAAATxjAAB
3 AAAZdQAAGAAATxjAAC
4 AAAZdQAAGAAATxjAAD
5 AAAZdQAAGAAATxjAAE
6 AAAZdQAAGAAATxjAAF
7 AAAZdQAAGAAATxjAAG
8 AAAZdQAAGAAATxjAAH
9 AAAZdQAAGAAATxjAAI
已选择8行。
SQL> select t.id,t.rowid from part_tab_rowid partition(p2) t;
ID ROWID
---------- ------------------
10 AAAZdRAAGAAATxrAAA
11 AAAZdRAAGAAATxrAAB
12 AAAZdRAAGAAATxrAAC
13 AAAZdRAAGAAATxrAAD
14 AAAZdRAAGAAATxrAAE
15 AAAZdRAAGAAATxrAAF
16 AAAZdRAAGAAATxrAAG
17 AAAZdRAAGAAATxrAAH
18 AAAZdRAAGAAATxrAAI
19 AAAZdRAAGAAATxrAAJ
12 AAAZdRAAGAAATxrAAK
已选择11行。
--由此可以发现,rowid的记录发生了改变。
---一般来说普通表的变更是不会变更rowid的,如下
create table normal_tab(id int);
insert into normal_tab1 select rownum from dual connect by rownum<=10;
commit;
select t.*,t.rowid from normal_tab t;
ID ROWID
---------- ------------------
1 AAAazDAAEAAATRdAAA
2 AAAazDAAEAAATRdAAB
3 AAAazDAAEAAATRdAAC
4 AAAazDAAEAAATRdAAD
5 AAAazDAAEAAATRdAAE
6 AAAazDAAEAAATRdAAF
7 AAAazDAAEAAATRdAAG
8 AAAazDAAEAAATRdAAH
9 AAAazDAAEAAATRdAAI
10 AAAazDAAEAAATRdAAJ
已选择10行。
update normal_tab set id=999 where id=1;
commit;
select t.*,t.rowid from normal_tab t;
ID ROWID
---------- ------------------
999 AAAazDAAEAAATRdAAA
2 AAAazDAAEAAATRdAAB
3 AAAazDAAEAAATRdAAC
4 AAAazDAAEAAATRdAAD
5 AAAazDAAEAAATRdAAE
6 AAAazDAAEAAATRdAAF
7 AAAazDAAEAAATRdAAG
8 AAAazDAAEAAATRdAAH
9 AAAazDAAEAAATRdAAI
10 AAAazDAAEAAATRdAAJ
已选择10行。
统计信息.
1. 传统的analyze的方式对收集分区表统计信息不准确。
2. 可以只收集某分区的统计信息
-- 范围分区示例
drop table range_part_tab purge;
--注意,此分区为范围分区
--例子1
create table range_part_tab (id number,deal_date date,area_code number,nbr number,contents varchar2(4000))
partition by range (deal_date)
(
partition p_201301 values less than (TO_DATE('2013-02-01', 'YYYY-MM-DD')),
partition p_201302 values less than (TO_DATE('2013-03-01', 'YYYY-MM-DD')),
partition p_201303 values less than (TO_DATE('2013-04-01', 'YYYY-MM-DD')),
partition p_201304 values less than (TO_DATE('2013-05-01', 'YYYY-MM-DD')),
partition p_201305 values less than (TO_DATE('2013-06-01', 'YYYY-MM-DD')),
partition p_201306 values less than (TO_DATE('2013-07-01', 'YYYY-MM-DD')),
partition p_201307 values less than (TO_DATE('2013-08-01', 'YYYY-MM-DD')),
partition p_201308 values less than (TO_DATE('2013-09-01', 'YYYY-MM-DD')),
partition p_201309 values less than (TO_DATE('2013-10-01', 'YYYY-MM-DD')),
partition p_201310 values less than (TO_DATE('2013-11-01', 'YYYY-MM-DD')),
partition p_201311 values less than (TO_DATE('2013-12-01', 'YYYY-MM-DD')),
partition p_201312 values less than (TO_DATE('2014-01-01', 'YYYY-MM-DD')),
partition p_201401 values less than (TO_DATE('2014-02-01', 'YYYY-MM-DD')),
partition p_201402 values less than (TO_DATE('2014-03-01', 'YYYY-MM-DD')),
partition p_max values less than (maxvalue)
)
;
--以下是插入2013年一整年日期随机数和表示福建地区号含义(591到599)的随机数记录,共有10万条,如下:
insert into range_part_tab (id,deal_date,area_code,nbr,contents)
select rownum,
to_date( to_char(sysdate-365,'J')+TRUNC(DBMS_RANDOM.VALUE(0,365)),'J'),
ceil(dbms_random.value(591,599)),
ceil(dbms_random.value(18900000001,18999999999)),
rpad('*',400,'*')
from dual
connect by rownum <= 100000;
commit;
--以下是插入2014年一整年日期随机数和表示福建地区号含义(591到599)的随机数记录,共有10万条,如下:
insert into range_part_tab (id,deal_date,area_code,nbr,contents)
select rownum,
to_date( to_char(sysdate,'J')+TRUNC(DBMS_RANDOM.VALUE(0,365)),'J'),
ceil(dbms_random.value(591,599)),
ceil(dbms_random.value(18900000001,18999999999)),
rpad('*',400,'*')
from dual
connect by rownum <= 100000;
commit;
exec dbms_stats.gather_table_stats(ownname => 'LJB',tabname => 'RANGE_PART_TAB',partname =>'p_201312', estimate_percent => 10,method_opt=> 'for all indexed columns',cascade=>TRUE) ;
set linesize 366
col partition_count format 99999
col num_rows format 99999999
col partition_name format a28
col table_name format a30
col last_analyzed format date
---收集完p_201312分区的统计结构后,可以通过如下方式查询到结果:
select table_name,
partition_name,
last_analyzed,
partition_position,
num_rows
from user_tab_statistics t
where table_name ='RANGE_PART_TAB';
TABLE_NAME PARTITION_NAME LAST_ANALYZED PARTITION_POSITION NUM_ROWS
------------------------------ ---------------------------- -------------- ------------------ ---------
RANGE_PART_TAB 01-12月-13 201230
RANGE_PART_TAB P_201301 1
RANGE_PART_TAB P_201302 2
RANGE_PART_TAB P_201303 3
RANGE_PART_TAB P_201304 4
RANGE_PART_TAB P_201305 5
RANGE_PART_TAB P_201306 6
RANGE_PART_TAB P_201307 7
RANGE_PART_TAB P_201308 8
RANGE_PART_TAB P_201309 9
RANGE_PART_TAB P_201310 10
RANGE_PART_TAB P_201311 11
RANGE_PART_TAB P_201312 01-12月-13 12 8474
RANGE_PART_TAB P_201401 13
RANGE_PART_TAB P_201402 14
RANGE_PART_TAB P_MAX 15
已选择16行。
数据字典信息:
---显示数据库所有分区表的信息:DBA_PART_TABLES
---显示表分区信息 显示数据库所有分区表的详细分区信息:DBA_TAB_PARTITIONS
---显示子分区信息 显示数据库所有组合分区表的子分区信息:DBA_TAB_SUBPARTITIONS
---显示分区列 显示数据库所有分区表的分区列信息:DBA_PART_KEY_COLUMNS
--显示子分区列 显示数据库所有分区表的子分区列信息:DBA_SUBPART_KEY_COLUMNS
--查看当前用户下分区表及对应索引的相关信息
--(表及索引多大,多少个分区,在哪一个列建了分区,表及索引的分区的类型是什么,有无子分区)
set linesize 366
col partitioning_type format a10
col subpartitioning_type format a10
col partition_count format 99999
col column_name format a20
col object_type format a10
col blevel format 9
col num_rows format 99999999
col leaf_blocks format 999999
col column_position format 9
col partition_name format a28
col segment_type format a20
col index_name format a28
col table_name format a30
col last_analyzed format date
col status format a8
---01 该表是否是分区表,分区表的分区类型是什么,是否有子分区,分区总数有多少
select partitioning_type,
subpartitioning_type,
partition_count
from user_part_tables
where table_name ='RANGE_PART_TAB';
--02 该分区表在哪一列上建分区,有无多列联合建分区
select column_name,
object_type,
column_position
from user_part_key_columns
where name ='RANGE_PART_TAB';
--03 该分区表有多大?
select sum(bytes) / 1024 / 1024
from user_segments
where segment_name ='RANGE_PART_TAB';
--04 该分区表各分区分别有多大,各个分区名是什么。
select partition_name,
segment_type,
bytes
from user_segments
where segment_name ='RANGE_PART_TAB';
--05 该分区表的统计信息收集情况
select table_name,
partition_name,
last_analyzed,
partition_position,
num_rows
from user_tab_statistics t
where table_name ='RANGE_PART_TAB';
--06 查该分区表有无索引,分别什么类型,全局索引是否失效,此外还可看统计信息收集情况。
--(其中status值为N/A 表示分区索引,分区索引是否失效是在user_ind_partitions中查看)
select table_name,
index_name,
last_analyzed,
blevel,
num_rows,
leaf_blocks,
distinct_keys,
status
from user_indexes
where table_name ='RANGE_PART_TAB';
--07 该分区表在哪些列上建了索引
select index_name,
column_name,
column_position
from user_ind_columns
where table_name = 'RANGE_PART_TAB';
--08 该分区表上的各索引分别有多大。
select segment_name,segment_type,sum(bytes)/1024/1024
from user_segments
where segment_name in
(select index_name
from user_indexes
where table_name ='RANGE_PART_TAB')
group by segment_name,segment_type ;
--09 该分区表的索引段的分配情况
select segment_name
partition_name,
segment_type,
bytes
from user_segments
where segment_name in
(select index_name
from user_indexes
where table_name ='RANGE_PART_TAB');
--10 分区索引相关信息及统计信息、是否失效查看。
select t2.table_name,
t1.index_name,
t1.partition_name,
t1.last_analyzed,
t1.blevel,
t1.num_rows,
t1.leaf_blocks,
t1.status
from user_ind_partitions t1, user_indexes t2
where t1.index_name = t2.index_name
and t2.table_name='RANGE_PART_TAB';