前提:sql
查詢分區:Select *From user_extents WHERE partition_name='分區名';數據庫
1)建立表空間 oracle
create tablespace HRPM0less
datafile '/oradata/misdb/HRPM0.DBF' size 5m autoextend on next 10m maxsize unlimited性能
2)刪除表空間(同時把數據文件也刪除) 測試
DROP TABLESPACE data01 INCLUDING CONTENTS AND DATAFILES;spa
若是不想刪除數據文件:對象
Drop tablespace tablespace_name;索引
3) 修改表空間大小 ip
alter database datafile '/path/NADDate05.dbf' resize 100M
4)添加數據文件(在創建表空間時,如果約束了表空間的大小,那麼一段時間後,這個表空間就會被裝滿,沒法再添加其餘對象。則須要給表空間添加數據文件):
Alter tablespace tablespace_name add datafile’ '/path/NADDate06.dbf’ size 100M;
4) 備註:
4.1).--.禁止undo tablespace自動增加
alter database datafile 'full_path\undotbs01.dbf' autoextend off;
4.2).-- 建立一個新的小空間的undo tablespace
create undo tablespace undotBS2 datafile 'full_path\UNDOTBS02.DBF' size 100m;
4.3).-- 設置新的表空間爲系統undo_tablespace
alter system set undo_tablespace=undotBS2;
4.4).-- Drop 舊的表空間
drop tablespace undotbs1 including contents;
4.5).--查看全部表空間的狀況
select * from dba_tablespaces
5)查到一個最好用的表:dict
5.1)select *from dict where table_name like '%PART%'
5.2)ALL_TAB_PARTITIONS:能夠查出表所對應的分區內容;
5.3)dab_tab_partitons :與上2);
5.4)dba_ind_partitons:查詢分區的索引;
5.5)子分區也是同樣的(dba_tab_subpartitons,dba_ind_partitons)
1、使用分區的優勢:
1、加強可用性:若是表的某個分區出現故障,表在其餘分區的數據仍然可用;
2、維護方便:若是表的某個分區出現故障,須要修復數據,只修復該分區便可;
3、均衡I/O:能夠把不一樣的分區映射到磁盤以平衡I/O,改善整個系統性能;
4、改善查詢性能:對分區對象的查詢能夠僅搜索本身關心的分區,提升檢索速度。
2、Oracle數據庫提供對錶或索引的分區方法有幾種(收集到四種):
1、範圍分區
2、列表分區
3、Hash分區(散列分區)
4、複合分區
3、詳描述分區實例:
1)下面將以實例的方式分別對這三種分區方法來講明分區表的使用。爲了測試方便,咱們先建三個表空間。
create tablespace dinya_space01 datafile 'C:\表空間\dinya01.dbf' size 5M; create tablespace dinya_space02 datafile 'C:\表空間\dinya02.dbf'SIZE 5M; create tablespace dinya_space03 datafile 'C:\表空間\dinya03.dbf' SIZE 5M;
select * from user_tablespaces
<表空間->三個>
1.1)範圍分區
範圍分區就是對數據表中的某個值的範圍進行分區,根據某個值的範圍,決定將該數據存儲在哪一個分區上。如根據序號分區,根據業務記錄的建立日期進行分區等。
需求描述:有一個物料交易表,表名:material_transactions。該表未來可能有千萬級的數據記錄數。要求在建該表的時候使用分區表。這時候咱們可使用序號分區三個區,每一個區中預計存儲三千萬的數據,也可使用日期分區,如每五年的數據存儲在一個分區上。
根據交易記錄的序號分區建表:----爲了測試須要作如下修改;
create table dinya_test
(
transaction_id number primary key,
item_id number(8) not null,
item_description varchar2(300),
transaction_date date not null
)
partition by range (transaction_id)
(
partition part_01 values less than(2) tablespace dinya_space01,-----2條如下的交易在此分區上:part_01
partition part_02 values less than(3) tablespace dinya_space02,-----等於+大於2而小於3的交易在此分區:part_02
partition part_03 values less than(maxvalue) tablespace dinya_space03----大於3的交易在此分區:part_03
-----------------以上在pl/sql測試成功;
---------------- 如下沒有在pl/sql測試!
根據交易日期分區建表:
SQL> create table dinya_test
(
transaction_id number primary key,
item_id number(8) not null,
item_description varchar2(300),
transaction_date date not null
)
partition by range (transaction_date)
(
partition part_01 values less than(to_date('2006-01-01','yyyy-mm-dd')) tablespace dinya_space01,
partition part_02 values less than(to_date('2010-01-01','yyyy-mm-dd')) tablespace dinya_space02,
partition part_03 values less than(maxvalue) tablespace dinya_space03
);
這樣咱們就分別建了以交易序號和交易日期來分區的分區表。每次插入數據的時候,系統將根據指定的字段的值來自動將記錄存儲到制定的分區(表空間)中。
固然,咱們還能夠根據需求,使用兩個字段的範圍分佈來分區,如partition by range ( transaction_id ,transaction_date),分區條件中的值也作相應的改變,請讀者自行測試。
---------------------------------以上沒有在pl/sql測試!
1.2) 範圍分區建立成功以後的相關操做測試;
a)向表添加測試數據:
insert into dinya_test values(1,12,'BOOKS',sysdate);
insert into dinya_test values(2,12, 'BOOKS',sysdate+30);
insert into dinya_test values(3,12, 'BOOKS',to_date('2006-05-30','yyyy-mm-dd'));
insert into dinya_test values(4,12, 'BOOKS',to_date('2007-06-23','yyyy-mm-dd'));
insert into dinya_test values(5,12, 'BOOKS',to_date('2011-02-26','yyyy-mm-dd'));
insert into dinya_test values(6,12, 'BOOKS',to_date('2011-04-30','yyyy-mm-dd'));
b)查詢
b.1)若是查詢全表數據
select * from dinya_test;以下圖:
< 全表數據>
select * from dinya_test partition(part_01);以下圖:
<Part_01分區的數據>
select * from dinya_test partition(part_02);以下圖:
<Part_02分區的數據>
select * from dinya_test partition(part_03);以下圖:
<Part_03分區的數據>
update dinya_test partition(part_01) t set t.item_description='DESK' where t.transaction_id=1;
select * from dinya_test partition(part_01);BOOKS->DESK(發生變化)
select * from dinya_test(此結果就不用查看了,確定變了);
---刪除part_03分區中transaction_id=4的記錄:
delete from dinya_test partition(part_03) t where t.transaction_id=4;
select * from dinya_test partition(part_03)
少了transaction_id=4的記錄(與上圖對比)
c)索引的建立:
c.1)局部索引的建立:
create index dinya_idx_t on dinya_test(item_id)
local
(
partition idx_1 tablespace dinya_space01,---分區名爲:idx_1
partition idx_2 tablespace dinya_space02, ---分區名爲:idx_2
partition idx_3 tablespace dinya_space03---分區名爲:idx_3
); ---pl/sql測試成功
注:
select *from ALL_TAB_PARTITIONS where table_name ='DINYA_TEST'
select *From dba_ind_partitions where partition_name='IDX_1'
c.2)全局索引的建立:
全局索引創建時global 子句容許指定索引的範圍值,這個範圍值爲索引字段的範圍值:
create index dinya_idx_t on dinya_test(item_id)
global partition by range(item_id)
(
partition idx_1 values less than (1000) tablespace dinya_space01,
partition idx_2 values less than (10000) tablespace dinya_space02,
partition idx_3 values less than (maxvalue) tablespace dinya_space03
);----PL/SQL末測試[參照以上local];
整個表建立索引:
Create index dinya_idx_t on dinya_test(item_id);
備註: select *from all_indexes(dba_indexes、all_ind_columns 、user_ind_columns 、 dba_ind_columns)
1.3) Hash分區(散列分區)
——————————如下沒有在機器上測試
散列分區爲經過指定分區編號來均勻分佈數據的一種分區類型,由於經過在I/O設備上進行散列分區,使得這些分區大小一致。如將物料交易表的數據根據交易ID散列地存放在指定的三個表空間中:
create table dinya_test
(
transaction_id number primary key,
item_id number(8) not null,
item_description varchar2(300),
transaction_date date
)
partition by hash(transaction_id)
(
partition part_01 tablespace dinya_space01,
partition part_02 tablespace dinya_space02,
partition part_03 tablespace dinya_space03
);
建表成功,此時插入數據,系統將按transaction_id將記錄散列地插入三個分區中,這裏也就是三個不一樣的表空間中。
——————————以上沒有在機器上測試;
1.4) 列表分區:該分區的特色是某列的值只有幾個,基於這樣的特色咱們能夠採用列表分區。
示例1:
CREATE TABLE PROBLEM_TICKETS
(
PROBLEM_ID NUMBER(7) NOT NULL PRIMARY KEY,
DESCRIPTION VARCHAR2(2000),
CUSTOMER_ID NUMBER(7) NOT NULL,
DATE_ENTERED DATE NOT NULL,
STATUS VARCHAR2(20)
)
PARTITION BY LIST (STATUS)
(
PARTITION PROB_ACTIVE VALUES ('ACTIVE') TABLESPACE PROB_TS01,
PARTITION PROB_INACTIVE VALUES ('INACTIVE') TABLESPACE PROB_TS02
)
備註:active和inactive是列status的值!謹記與range和hash分區的區別;
1.4.1)測試以下:
insert into PROBLEM_TICKETS values(1,'BOOKS',1,sysdate,'ACTIVE');
insert into PROBLEM_TICKETS values(2,'son',2,sysdate+30,'INACTIVE');
insert into PROBLEM_TICKETS values(3,'son',3,to_date('2006-05-30','yyyy-mm-dd'),'INACTIVE');
insert into PROBLEM_TICKETS values(4,'BOOKS',4,to_date('2007-06-23','yyyy-mm-dd'),'INACTIVE');
insert into PROBLEM_TICKETS values(5,'old',5,to_date('2011-02-26','yyyy-mm-dd'),'ACTIVE');
insert intoPROBLEM_TICKETSvalues(6,'test',6,to_date('2011-04-30','yyyy-mm-dd'),'INACTIVE');
select * from PROBLEM_TICKETS
<查詢全表>
1.4.2)
select * from PROBLEM_TICKETS partition(PROB_ACTIVE)
1.4.2)
select * from PROBLEM_TICKETS partition(PROB_INACTIVE)
在測試中遇到這樣的狀況。若是表建立了分區,若是要刪除數據文件(表空間文件),則要先刪除分區,而後才能刪除數據文件(可是在刪除數據文件時,必需要保留一個分區才能最終刪除數據文件>表空間文件,)
固然,也能夠直接就刪除表也行,剛全部的全刪除,可是表空間文件還在!
1.5) 複合分區
有時候咱們須要根據範圍分區後,每一個分區內的數據再散列地分佈在幾個表空間中,這樣咱們就要使用複合分區。複合分區是先使用範圍分區,而後在每一個分區內再使用散列分區的一種分區方法,如將物料交易的記錄按時間分區,而後每一個分區中的數據分三個子分區,將數據散列地存儲在三個指定的表空間中:
create table dinya_test
(
transaction_id number primary key,
item_id number(8) not null,
item_description varchar2(300),
transaction_date date
)
partition by range(transaction_date)subpartition by hash(transaction_id)
subpartitions 3 store in (dinya_space07,dinya_space08,dinya_space09)
(
partition part_07 values less than(to_date('2006-01-01','yyyy-mm-dd')),
partition part_08 values less than(to_date('2010-01-01','yyyy-mm-dd')),
partition part_09 values less than(maxvalue)
);
---測試以下:
select *From user_tab_partitions where table_name=upper('dinya_test')
selec *From user_tab_subpartitions where table_name=upper('dinya_test')
《圖1》
插入以下數據:
insert into dinya_test values(1,12,'BOOKS',sysdate);
insert into dinya_test values(2,12, 'BOOKS',sysdate+30);
insert into dinya_test values(3,12, 'BOOKS',to_date('2006-05-30','yyyy-mm-dd'));
insert into dinya_test values(7,12, 'BOOKS',to_date('2005-05-30','yyyy-mm-dd'));
insert into dinya_test values(4,12, 'BOOKS',to_date('2007-06-23','yyyy-mm-dd'));
insert into dinya_test values(5,12, 'BOOKS',to_date('2011-02-26','yyyy-mm-dd'));
insert into dinya_test values(6,12, 'BOOKS',to_date('2011-04-30','yyyy-mm-dd'));
select *From dinya_test:以下圖
select *From dinya_test partition(part_07)以下圖:
select *From dinya_test partition(part_09)
參照下圖,按所顯的子分區名,看可否查出數據:
select*Fromuser_tab_subpartitions where table_name=upper('dinya_test')
select *From dinya_test subpartition(SYS_SUBP62):以下圖:
其它的查詢同樣。-----測試成功;
備註: 該例中,先是根據交易日期進行範圍分區,而後根據交易的ID將記錄散列地存儲在三個表空間中。
1.6) 複合範圍列表分區:這種分區是基於範圍分區和列表分區,表首先按某列進行範圍分區,而後再按某列進行列表分區,分區之中的分區被稱爲子分區。
示例1:
Create table sales
(
Product_id varchar2(5),
Sales_date date,
Sales_cost number(10),
Status varchar2(20)
)
Partition by range(Sales_cost)
Subpartition by list(status)
(
Partition p1 values less than (1) tablespace dinya_space01
(
Subpartition p1sub1 values('ACTIVE') tablespace dinya_space03,
Subpartition p1sub2 values('INACTIVE') tablespace dinya_space04
),
Partition p2 values less than (3) tablespace dinya_space02
(
Subpartition p1sub3 values('ACTIVE') tablespace dinya_space05,
Subpartition p1sub4 values('INACTIVE') tablespace dinya_space06
)
)測試以下:
insert into sales values(1,sysdate,0.1,'ACTIVE');
insert into sales values(2,sysdate+30,1,'INACTIVE');
insert into sales
values(3,to_date('2006-05-30','yyyy-mm-dd'),2,'INACTIVE');
select *From sales:
Select *from sales partition(p2)
SELECT * FROM SALES SUBPARTITION(p1sub4)
SELECT * FROM SALES SUBPARTITION(p1sub3)
沒有數據!!
select *From dba_tab_subpartitions where table_name='SALES'
有關表分區的一些維護性操做:
1、添加分區
如下代碼給SALES表添加了一個P3分區
ALTER TABLE SALES ADD PARTITION P3 VALUES LESS THAN(TO_DATE('2003-06-01','YYYY-MM-DD'));
注意:以上添加的分區界限應該高於最後一個分區界限。
如下代碼給SALES表的P3分區添加了一個P3SUB1子分區
ALTER TABLE SALES MODIFY PARTITION P3 ADD SUBPARTITION P3SUB1 VALUES('COMPLETE');
2、刪除分區
如下代碼刪除了P3表分區:
ALTER TABLE SALES DROP PARTITION P3;
在測試中遇到這樣的狀況。若是表建立了分區,若是要刪除數據文件(表空間文件),則要先刪除分區,而後才能刪除數據文件(可是在刪除數據文件時,必需要保留一個分區才能最終刪除數據文件>表空間文件,)
固然,也能夠直接就刪除表也行,剛全部的全刪除,可是表空間文件還在!
在如下代碼刪除了P4SUB1子分區:
ALTER TABLE SALES DROP SUBPARTITION P4SUB1;
注意:若是刪除的分區是表中惟一的分區,那麼此分區將不能被刪除,要想刪除此分區,必須刪除表。
3、截斷分區
截斷某個分區是指刪除某個分區中的數據,並不會刪除分區,也不會刪除其它分區中的數據。當表中即便只有一個分區時,也能夠截斷該分區。經過如下代碼截斷分區:
ALTER TABLE SALES TRUNCATE PARTITION P2;
經過如下代碼截斷子分區:
ALTER TABLE SALES TRUNCATE SUBPARTITION P2SUB2;
4、合併分區
合併分區是將相鄰的分區合併成一個分區,結果分區將採用較高分區的界限,值得注意的是,不能將分區合併到界限較低的分區。如下代碼實現了P1 P2分區的合併:
ALTER TABLE SALES MERGE PARTITIONS P1,P2 INTO PARTITION P2;
5、拆分分區
拆分分區將一個分區拆分兩個新分區,拆分後原來分區再也不存在。注意不能對HASH類型的分區進行拆分。
ALTER TABLE SALES SBLIT PARTITION P2 AT(TO_DATE('2003-02-01','YYYY-MM-DD'))
INTO (PARTITION P21,PARTITION P22);
6、接合分區(coalesca)
結合分區是將散列分區中的數據接合到其它分區中,當散列分區中的數據比較大時,能夠增長散列分區,而後進行接合,值得注意的是,接合分區只能用於散列分區中。經過如下代碼進行接合分區:
ALTER TABLE SALES COALESCA PARTITION;
7、重命名錶分區
如下代碼將P21更改成P2
ALTER TABLE SALES RENAME PARTITION P21 TO P2;
9、跨分區查詢
select sum( *) from (
(select count(*) cn from t_table_SS PARTITION (P200709_1)
union all
select count(*) cn from t_table_SS PARTITION (P200709_2));
10、查詢表上有多少分區
SELECT * FROM useR_TAB_PARTITIONS WHERE TABLE_NAME='tableName'
--顯示數據庫全部分區表的信息:
select * from DBA_PART_TABLES where table_name=upper('dinya_test')
--顯示當前用戶可訪問的全部分區表信息:
select * from ALL_PART_TABLES
同上圖
--顯示當前用戶全部分區表的信息:
select * from USER_PART_TABLES
同上圖
--顯示錶分區信息 顯示數據庫全部分區表的詳細分區信息:
select * from DBA_TAB_PARTITIONS
--顯示當前用戶可訪問的全部分區表的詳細分區信息:
select * from ALL_TAB_PARTITIONS
--顯示當前用戶全部分區表的詳細分區信息:
select * from USER_TAB_PARTITIONS
--顯示子分區信息 顯示數據庫全部組合分區表的子分區信息:
select * from DBA_TAB_SUBPARTITIONS
--顯示當前用戶可訪問的全部組合分區表的子分區信息:
select * from ALL_TAB_SUBPARTITIONS
--顯示當前用戶全部組合分區表的子分區信息:
select * from USER_TAB_SUBPARTITIONS
--顯示分區列 顯示數據庫全部分區表的分區列信息:
select * from DBA_PART_KEY_COLUMNS
--顯示當前用戶可訪問的全部分區表的分區列信息:
select * from ALL_PART_KEY_COLUMNS
--顯示當前用戶全部分區表的分區列信息:
select * from USER_PART_KEY_COLUMNS
--顯示子分區列 顯示數據庫全部分區表的子分區列信息:
select * from DBA_SUBPART_KEY_COLUMNS
--顯示當前用戶可訪問的全部分區表的子分區列信息:
select * from ALL_SUBPART_KEY_COLUMNS
--顯示當前用戶全部分區表的子分區列信息:
select * from USER_SUBPART_KEY_COLUMNS
--怎樣查詢出oracle數據庫中全部的的分區表
select * from user_tables a where a.partitioned='YES'
--刪除一個表的數據是
truncate table table_name;
--刪除分區表一個分區的數據是
alter table table_name truncate partition p5;
注:分區根據具體狀況選擇。
表分區有如下優勢:
1、數據查詢:數據被存儲到多個文件上,減小了I/O負載,查詢速度提升。
2、數據修剪:保存歷史數據很是的理想。
3、備份:將大表的數據分紅多個文件,方便備份和恢復。
4、並行性:能夠同時向表中進行DML操做,並行性性能提升。
================================================
索引:
1、通常索引:
create index index_name on table(col_name);
2、Oracle 分區索引詳解
語法:Table Index
CREATE [UNIQUE|BITMAP] INDEX [schema.]index_name
ON [schema.]table_name [tbl_alias]
(col [ASC | DESC]) index_clause index_attribs
index_clauses:
分如下兩種狀況
1. Local Index
就是索引信息的存放位置依賴於父表的Partition信息,換句話說建立這樣的索引必須保證父表是Partition
1.1 索引信息存放在父表的分區所在的表空間。可是僅能夠建立在父表爲HashTable或者composite分區表的。
LOCAL STORE IN (tablespace)
1.2 僅能夠建立在父表爲HashTable或者composite分區表的。而且指定的分區數目要與父表的分區數目要一致
LOCAL STORE IN (tablespace) (PARTITION [partition [LOGGING|NOLOGGING] [TABLESPACE {tablespace|DEFAULT}] [PCTFREE int] [PCTUSED int] [INITRANS int] [MAXTRANS int] [STORAGE storage_clause] [STORE IN {tablespace_name|DEFAULT] [SUBPARTITION [subpartition [TABLESPACE tablespace]]]])
1.3 索引信息存放在父表的分區所在的表空間,這種語法最簡單,也是最經常使用的分區索引建立方式。
Local
1.4 而且指定的Partition 數目要與父表的Partition要一致
LOCAL (PARTITION [partition
[LOGGING|NOLOGGING]
[TABLESPACE {tablespace|DEFAULT}]
[PCTFREE int]
[PCTUSED int]
[INITRANS int]
[MAXTRANS int]
[STORAGE storage_clause]
[STORE IN {tablespace_name|DEFAULT]
[SUBPARTITION [subpartition [TABLESPACE tablespace]]]])
Global Index
索引信息的存放位置與父表的Partition信息徹底不相干。甚至父表是否是分區表都無所謂的。語法以下:
GLOBAL PARTITION BY RANGE (col_list)
( PARTITION partition VALUES LESS THAN (value_list)
[LOGGING|NOLOGGING]
[TABLESPACE {tablespace|DEFAULT}]
[PCTFREE int]
[PCTUSED int]
[INITRANS int]
[MAXTRANS int]
[STORAGE storage_clause] )
可是在這種狀況下,若是父表是分區表,要刪除父表的一個分區都必需要更新Global Index ,不然索引信息不正確
ALTER TABLE TableName DROP PARTITION PartitionName Update Global Indexes
--查詢索引
select object_name,object_type,tablespace_name,sum(value)
from v$segment_statistics
where statistic_name IN ('physical reads','physical write','logical reads')and object_type='INDEX'
group by object_name,object_type,tablespace_name
order by 4 desc