原文链接:http://soft.chinabyte.com/database/182/12307682.shtml
此文从以下几个方面来整理关于分区表的概念及操作:1.表空间及分区表的概念2.表分区的具体作用3.表分区的优缺点4.表分区的几种类型及操作方法5.对表分区的维护性操作。
(1.) 表空间及分区表的概念表空间: 是一个或多个数据文件的集合,所有的数据对象都存放在指定的表空间中,但主要存放的是表,所以称作表空间。
分区表:当表中的数据量不断增大,查询数据的速度就会变慢,应用程序的性能就会下降,这时就应该考虑对表进行分区。表进行分区后,逻辑上表仍然是一张完整的表,只是将表中的数据在物理上存放到多个表空间(物理文件上),这样查询数据时,不至于每次都扫描整张表。
( 2)。表分区的具体作用Oracle的表分区功能通过改善可管理性、性能和可用性,从而为各式应用程序带来了极大的好处。通常,分区可以使某些查询以及维护操作的性能大大提高。此外,分区还可以极大简化常见的管理任务,分区是构建千兆字节数据系统或超高可用性系统的关键工具。
分区功能能够将表、索引或索引组织表进一步细分为段,这些数据库对象的段叫做分区。每个分区有自己的名称,还可以选择自己的存储特性。从数据库管理员的角度来看,一个分区后的对象具有多个段,这些段既可进行集体管理,也可单独管理,这就使数据库管理员在管理分区后的对象时有相当大的灵活性。但是,从应用程序的角度来看,分区后的表与非分区表完全相同,使用 SQL DML 命令访问分区后的表时,无需任何修改。
什么时候使用分区表:1、表的大小超过2GB. 2、表中包含历史数据,新的数据被增加都新的分区中。
(3)。表分区的优缺点表分区有以下优点:1、改善查询性能:对分区对象的查询可以仅搜索自己关心的分区,提高检索速度。
2、增强可用性:如果表的某个分区出现故障,表在其他分区的数据仍然可用;3、维护方便:如果表的某个分区出现故障,需要修复数据,只修复该分区即可;4、均衡I/O:可以把不同的分区映射到磁盘以平衡I/O,改善整个系统性能。
缺点:分区表相关:已经存在的表没有方法可以直接转化为分区表。不过 Oracle 提供了在线重定义表的功能。
(4)。表分区的几种类型及操作方法一。范围分区:范围分区将数据基于范围映射到每一个分区,这个范围是你在创建分区时指定的分区键决定的。这种分区方式是最为常用的,并且分区键经常采用日期。举个例子:你可能会将销售数据按照月份进行分区。
当使用范围分区时,请考虑以下几个规则:1、每一个分区都必须有一个VALUES LESS THEN子句,它指定了一个不包括在该分区中的上限值。分区键的任何值等于或者大于这个上限值的记录都会被加入到下一个高一些的分区中。
2、所有分区,除了第一个,都会有一个隐式的下限值,这个值就是此分区的前一个分区的上限值。
3、在最高的分区中,MAXVALUE被定义。MAXVALUE代表了一个不确定的值。这个值高于其它分区中的任何分区键的值,也可以理解为高于任何分区中指定的VALUE LESS THEN的值,同时包括空值。
例一:假设有一个CUSTOMER表,表中有数据200000行,我们将此表通过CUSTOMER_ID进行分区,每个分区存储100000行,我们将每个分区保存到单独的表空间中,这样数据文件就可以跨越多个物理磁盘。下面是创建表和分区的代码,如下:CREATE TABLE CUSTOMER(CUSTOMER_ID NUMBER NOT NULL PRIMARY KEY,FIRST_NAME VARCHAR2(30) NOT NULL,LAST_NAME VARCHAR2(30) NOT NULL,PHONE VARCHAR2(15) NOT NULL,EMAIL VARCHAR2(80),STATUS CHAR(1))
PARTITION BY RANGE (CUSTOMER_ID)
(PARTITION CUS_PART1 VALUES LESS THAN (100000) TABLESPACE CUS_TS01,PARTITION CUS_PART2 VALUES LESS THAN (200000) TABLESPACE CUS_TS02)
例二:按时间划分CREATE TABLE ORDER_ACTIVITIES(ORDER_ID NUMBER(7) NOT NULL,ORDER_DATE DATE,TOTAL_AMOUNT NUMBER,CUSTOTMER_ID NUMBER(7),PAID CHAR(1))
PARTITION BY RANGE (ORDER_DATE)
(PARTITION ORD_ACT_PART01 VALUES LESS THAN (TO_DATE('01- MAY -2003','DD-MON-YYYY')) TABLESPACEORD_TS01,PARTITION ORD_ACT_PART02 VALUES LESS THAN (TO_DATE('01-JUN-2003','DD-MON-YYYY')) TABLESPACE ORD_TS02,PARTITION ORD_ACT_PART02 VALUES LESS THAN (TO_DATE('01-JUL-2003','DD-MON-YYYY')) TABLESPACE ORD_TS03)
例三:MAXVALUE CREATE TABLE RangeTable(idd INT PRIMARY KEY ,iNAME VARCHAR(10),grade INT)
PARTITION BY RANGE (grade)
(PARTITION part1 VALUES LESS THEN (1000) TABLESPACE Part1_tb,PARTITION part2 VALUES LESS THEN (MAXVALUE) TABLESPACE Part2_tb);
二。列表分区:该分区的特点是某列的值只有几个,基于这样的特点我们可以采用列表分区。
例一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例二CREATE TABLE ListTable(id INT PRIMARY KEY ,name VARCHAR (20),area VARCHAR (10))
PARTITION BY LIST (area)
(PARTITION part1 VALUES ('guangdong','beijing') TABLESPACE Part1_tb,PARTITION part2 VALUES ('shanghai','nanjing') TABLESPACE Part2_tb);)
三。散列分区:这类分区是在列值上使用散列算法,以确定将行放入哪个分区中。当列的值没有合适的条件时,建议使用散列分区。
散列分区为通过指定分区编号来均匀分布数据的一种分区类型,因为通过在I/O设备上进行散列分区,使得这些分区大小一致。
例一:CREATE TABLE HASH_TABLE(COL NUMBER(8),INF VARCHAR2(100))
PARTITION BY HASH (COL)
(PARTITION PART01 TABLESPACE HASH_TS01,PARTITION PART02 TABLESPACE HASH_TS02,PARTITION PART03 TABLESPACE HASH_TS03)
简写:CREATE TABLE emp(empno NUMBER (4),ename VARCHAR2 (30),sal NUMBER)
PARTITION BY HASH (empno) PARTITIONS 8 STORE IN (emp1,emp2,emp3,emp4,emp5,emp6,emp7,emp8);
hash分区最主要的机制是根据hash算法来计算具体某条纪录应该插入到哪个分区中,hash算法中最重要的是hash函数,Oracle中如果你要使用hash分区,只需指定分区的数量即可。建议分区的数量采用2的n次方,这样可以使得各个分区间数据分布更加均匀。
四。组合范围散列分区这种分区是基于范围分区和列表分区,表首先按某列进行范围分区,然后再按某列进行列表分区,分区之中的分区被称为子分区。
CREATE TABLE SALES(PRODUCT_ID VARCHAR2(5),SALES_DATE DATE,SALES_COST NUMBER(10),STATUS VARCHAR2(20))
PARTITION BY RANGE(SALES_DATE) SUBPARTITION BY LIST (STATUS)
(PARTITION P1 VALUES LESS THAN(TO_DATE('2003-01-01','YYYY-MM-DD'))TABLESPACE rptfact2009(SUBPARTITION P1SUB1 VALUES ('ACTIVE') TABLESPACE rptfact2009,SUBPARTITION P1SUB2 VALUES ('INACTIVE') TABLESPACE rptfact2009),PARTITION P2 VALUES LESS THAN (TO_DATE('2003-03-01','YYYY-MM-DD')) TABLESPACE rptfact2009(SUBPARTITION P2SUB1 VALUES ('ACTIVE') TABLESPACE rptfact2009,SUBPARTITION P2SUB2 VALUES ('INACTIVE') TABLESPACE rptfact2009)
五。复合范围散列分区:这种分区是基于范围分区和散列分区,表首先按某列进行范围分区,然后再按某列进行散列分区。
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_space01,dinya_space02,dinya_space03)
(partition part_01 values less than(to_date(‘2006-01-01’,‘yyyy-mm-dd’)),partition part_02 values less than(to_date(‘2010-01-01’,‘yyyy-mm-dd’)),partition part_03 values less than(maxvalue));
(5)。有关表分区的一些维护性操作:一、添加分区以下代码给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');二、删除分区以下代码删除了P3表分区:ALTER TABLE SALES DROP PARTITION P3;在以下代码删除了P4SUB1子分区:ALTER TABLE SALES DROP SUBPARTITION P4SUB1;注意:如果删除的分区是表中唯一的分区,那么此分区将不能被删除,要想删除此分区,必须删除表。
三、截断分区截断某个分区是指删除某个分区中的数据,并不会删除分区,也不会删除其它分区中的数据。当表中即使只有一个分区时,也可以截断该分区。通过以下代码截断分区:ALTER TABLE SALES TRUNCATE PARTITION P2;通过以下代码截断子分区:ALTER TABLE SALES TRUNCATE SUBPARTITION P2SUB2;四、合并分区合并分区是将相邻的分区合并成一个分区,结果分区将采用较高分区的界限,值得注意的是,不能将分区合并到界限较低的分区。以下代码实现了P1 P2分区的合并:ALTER TABLE SALES MERGE PARTITIONS P1,P2 INTO PARTITION P2;五、拆分分区拆分分区将一个分区拆分两个新分区,拆分后原来分区不再存在。注意不能对HASH类型的分区进行拆分。
ALTER TABLE SALES SBLIT PARTITION P2 AT(TO_DATE('2003-02-01','YYYY-MM-DD')) INTO (PARTITION P21,PARTITION P22);六、接合分区(coalesca)
结合分区是将散列分区中的数据接合到其它分区中,当散列分区中的数据比较大时,可以增加散列分区,然后进行接合,值得注意的是,接合分区只能用于散列分区中。通过以下代码进行接合分区:ALTER TABLE SALES COALESCA PARTITION;七、重命名表分区以下代码将P21更改为P2 ALTER TABLE SALES RENAME PARTITION P21 TO P2;八、相关查询跨分区查询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));查询表上有多少分区SELECT * FROM useR_TAB_PARTITIONS WHERE TABLE_NAME='tableName'查询索引信息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
——显示数据库所有分区表的信息:select * from DBA_PART_TABLES
——显示当前用户可访问的所有分区表信息: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;
「PS」:当update更改数据所属分区时,必须赋予表row movement权限。
alter table test_partition_tab enable/disable row movement;update分区字段,改变所属分区,数据在内部变化是经过了源数据插入新分区、新数据更新、源老数据删除的步骤,因此rowid将会改变;数据索引也将重走。
----------------------------表区分查询----------------------------------
select * from dba_tab_partitions where table_name='XXXX'
select * from XXXX PARTITION(XXXXX)
----------------------------分区类型----------------------------------
・RANGE
・HASH
・SYSTEM
・LIST
・REFERENCE
创建不同的分区类型后,在该分区上建立索引后,所建的索引也是分区的类型。
CREATE TABLE HASH_INDEX_TEST (DEPTNO NUMBER, DEPTNAME VARCHAR(32))
PARTITION BY HASH(DEPTNO) PARTITIONS 16
TABLESPACE space_01
/
ALTER TABLE HASH_INDEX_TEST
ADD CONSTRAINT PK__HASH_INDEX_TEST PRIMARY KEY (DEPTNO)
USING INDEX (CREATE UNIQUE INDEX PK__HASH_INDEX_TEST ON HASH_INDEX_TEST (DEPTNO)
TABLESPACE space_01)
/
CREATE INDEX IND_HASH_INDEX_TEST_01 ON HASH_INDEX_TEST (DEPTNO, DEPTNAME) GLOBAL
PARTITION BY HASH (DEPTNO, DEPTNAME)
TABLESPACE space_01
----------------------------关于不同的分区放到不同的表空间----------------------------------
如果说是为了提高性能,那么,为什么放到不同的tablespace里面就可以提害尝愤妒莅德缝泉俯沪高性能呢?
好像要看你分区是怎么分的. 如果是 RANGE 分区, 这个一般是为了将来维护时候, 方便维护。 例如你的系统, 是一个销售的系统,销售数据是按年分区的。一般老板不会去查询 10年前某一天 某一笔销售, 卖了什么的细节信息的。因此, 数据库里面, 就保持有最近 10年的数据, 超过10年的, 就 从分区里面移除掉。好比现在是 2013年, 那么 我现在要把 2003 年的销售数据的那个分区, 移除掉。然后把这个分区的文件备份一下。就不管了。这种情况下, 如果不同的分区, 在不同的tablespace里面, 那么分区移除以后, 简单的复制那几个 表空间的文件, 就完成备份了,删除也是简单删除。如果不同的分区,在同一个tablespace里面, 一来没法简单的备份, 二来也不方便清理。如果是那种 HASH 分区, 那么有可能是为了提高性能, 害尝愤妒莅德缝泉俯沪不过这个是要求, 不同的表空间, 在不同的磁盘上面。 例如遇到那种很高频的 插入数据处理。 假设你有 3个分区, 各个分区都有单独的表空间。分别位于3块硬盘上面。那么 最耗时得磁盘读写 操作会分摊到 3块磁盘上去并行处理。最后一点嘛, 就是, 如果某一个表空间的文件坏了, 如果你是 一个分区一个表空间的话, 那么查询只会影响到那个 坏的分区, 而不影响其它分区例如 你的分区有5个, 分别是 2013, 2012, 2011, 2010, 2009。因为磁盘故障, 那个 2009 分区所在的表空间的文件无法访问了。但是你 查询 2013-2010 之间的数据, 还是没有问题的。但是如果所有分区, 都在一个表空间的话, 只要表空间文件挂了, 那么所有分区都挂了。
partition 優點:
1. parallel 存取 (提高 cpu 使用率)
2. 如果partition 放在不同 Datafile 或 Tablespace 下,可以各別管理( offline, read only)
3. 如果放在不同磁碟,可以同時存取硬碟,加快存取速度
我有一个大表,表分区是按照每天一个创建的。在使用的时候,我要查询一个时间段的数据(大概15天),也就是说需要跨15个表分区,这样查询起来比没有表分区会更慢吗?比15天创建一个表分区又怎样?求高手指点!!! 分享到:
举报违规检举侵权投诉|2012-04-18 02:10 提问者采纳
1、你这种情况,分区表上的查询比没分区的表快。 访问数据有两种方式,一是全表扫,二是先走索引、再通过索引返回的rowid访问表。 不分区表全表扫时,分区表快。分区表扫描的只是15个分区而不是全表,很显然扫描的数据量小,表里存的数据越多这个优势越明显。 不分区表走索引的时,仍然是分区表快。oracle会自动用扫描15个分区的方案来代替先索引后表这种2步的方案,由于分区后省去访问索引因此访问的数据量小,而且扫描分区是使用db file scattered read一次读多个数据块,速度比先索引后表的db file sequential read一次读一个数据块快很多,每天的数据越多这个优势越明显。 如果考虑开并行,分区表会比没分区的表快更多。2、根据你的查询来看,我觉得15天1个分区不如1天1个分区。 比如查1号到15号15天的数据,1天1个分区需要访问1号到15号的数据;查2号到16号15天的数据,1天1个分区需要访问2号到16号的数据。 但是如果15天1个分区: 查1号到15号15天的数据,15天1个分区需要访问1号到15号的数据;查2号到16号15天的数据,15天1个分区需要访问1号到30号的数据,也就是说查询时间段跨2个分区时,比上面的方案多访问1倍的数据量,自然会慢不少。(如果每天的数据较多,15天1个分区,通过索引访问2号到16号的数据会比全扫1号到30号2个分区更慢)