iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >Oracle 学习之 性能优化(十二) 分区表
  • 229
分享到

Oracle 学习之 性能优化(十二) 分区表

2024-04-02 19:04:59 229人浏览 泡泡鱼
摘要

一、分区概念   oracle允许将表、索引、索引组织表细分成更小的片,每个片我们称之为分区。分区有其自己的名字和存储参数。  如下图:每行数据只能属于一个分区,分区键决定数据

一、分区概念 

  oracle允许将表、索引、索引组织表细分成更小的片,每个片我们称之为分区。分区有其自己的名字和存储参数。

  如下图:

Oracle 学习之 性能优化(十二) 分区表

每行数据只能属于一个分区,分区键决定数据行属于哪个分区。分区键由一个或多个列组成。Oracle自动的将数据的DML操作映射到相应的分区中。

何时使用分区表:

  • Tables greater than 2 GB should always be considered as candidates for partitioning.

  • Tables containing historical data, in which new data is added into the newest partition. A typical example is a historical table where only the current month's data is updatable and the other 11 months are read only.

  • When the contents of a table must be distributed across different types of storage devices.

何时使用分区索引:

  • Avoid rebuilding the entire index when data is removed.

  • PerfORM maintenance on parts of the data without invalidating the entire index.

  • Reduce the effect of index skew caused by an index on a column with a monotonically increasing value.


分区的优点:

  分区裁剪,DML操作的数据如果可以定位到某个或者某些分区,那么只需对这部分数据进行读写。

  分区智能join,如果关联查询只需用到部分分区,那么避免了全表数据的扫描。

  易于维护数据。

分区策略:

  LIST、RANGE、HASH、SYSTEM、INTERVAL、reference、虚拟列分区。

表分区类型:

 单级别分区

Oracle 学习之 性能优化(十二) 分区表

组合分区

 Oracle 学习之 性能优化(十二) 分区表




索引分区类型:

本地分区

Oracle 学习之 性能优化(十二) 分区表


全局分区

Oracle 学习之 性能优化(十二) 分区表

全局索引

Oracle 学习之 性能优化(十二) 分区表


二、创建分区

创建LIST分区

sql> CREATE TABLE accounts
( id             NUMBER
, account_number NUMBER
, customer_id    NUMBER
, branch_id      NUMBER
, region         VARCHAR(2)
, status         VARCHAR2(1)
)
PARTITION BY LIST (region)
( PARTITION p_northwest VALUES ('OR', 'WA')
, PARTITION p_southwest VALUES ('AZ', 'UT', 'NM')
, PARTITION p_northeast VALUES ('NY', 'VM', 'NJ')
, PARTITION p_southeast VALUES ('FL', 'GA')
, PARTITION p_northcentral VALUES ('SD', 'WI')
, PARTITION p_southcentral VALUES ('OK', 'TX')
);
Table created.

SQL>

插入数据

SET DEFINE OFF;
Insert into SCOTT.ACCOUNTS
   (ID, ACCOUNT_NUMBER, CUSTOMER_ID, BRANCH_ID, REGION, 
    STATUS)
 Values
   (378326946, 894594273, 1292607495, 142784215, 'OR', 
    'k');
Insert into SCOTT.ACCOUNTS
   (ID, ACCOUNT_NUMBER, CUSTOMER_ID, BRANCH_ID, REGION, 
    STATUS)
 Values
   (584618757, 1364130187, 438768827, 554439762, 'WA', 
    'o');
Insert into SCOTT.ACCOUNTS
   (ID, ACCOUNT_NUMBER, CUSTOMER_ID, BRANCH_ID, REGION, 
    STATUS)
 Values
   (41523719, 656248010, 469613013, 1849874408, 'OR', 
    'o');
Insert into SCOTT.ACCOUNTS
   (ID, ACCOUNT_NUMBER, CUSTOMER_ID, BRANCH_ID, REGION, 
    STATUS)
 Values
   (1484487356, 1308908163, 1088179442, 1201623497, 'OR', 
    'w');
Insert into SCOTT.ACCOUNTS
   (ID, ACCOUNT_NUMBER, CUSTOMER_ID, BRANCH_ID, REGION, 
    STATUS)
 Values
   (151951677, 2077813008, 139635883, 1324220110, 'OR', 
    'L');
Insert into SCOTT.ACCOUNTS
   (ID, ACCOUNT_NUMBER, CUSTOMER_ID, BRANCH_ID, REGION, 
    STATUS)
 Values
   (537989506, 1256709056, 5665768, 1397516214, 'WA', 
    'j');
Insert into SCOTT.ACCOUNTS
   (ID, ACCOUNT_NUMBER, CUSTOMER_ID, BRANCH_ID, REGION, 
    STATUS)
 Values
   (1054752157, 511468132, 2033193426, 183536554, 'WA', 
    'q');
Insert into SCOTT.ACCOUNTS
   (ID, ACCOUNT_NUMBER, CUSTOMER_ID, BRANCH_ID, REGION, 
    STATUS)
 Values
   (2038555798, 1761488065, 1281290484, 1134105071, 'OR', 
    'y');
Insert into SCOTT.ACCOUNTS
   (ID, ACCOUNT_NUMBER, CUSTOMER_ID, BRANCH_ID, REGION, 
    STATUS)
 Values
   (1749170397, 1025971133, 1336822659, 219993587, 'OR', 
    'G');
Insert into SCOTT.ACCOUNTS
   (ID, ACCOUNT_NUMBER, CUSTOMER_ID, BRANCH_ID, REGION, 
    STATUS)
 Values
   (1308900569, 1076156248, 496158144, 1160914382, 'OR', 
    'Z');
Insert into SCOTT.ACCOUNTS
   (ID, ACCOUNT_NUMBER, CUSTOMER_ID, BRANCH_ID, REGION, 
    STATUS)
 Values
   (1742657481, 1697703100, 1276715127, 249769402, 'OR', 
    'g');
Insert into SCOTT.ACCOUNTS
   (ID, ACCOUNT_NUMBER, CUSTOMER_ID, BRANCH_ID, REGION, 
    STATUS)
 Values
   (1730173163, 690868494, 420676729, 1001701868, 'OR', 
    'K');
Insert into SCOTT.ACCOUNTS
   (ID, ACCOUNT_NUMBER, CUSTOMER_ID, BRANCH_ID, REGION, 
    STATUS)
 Values
   (1113431343, 1306177470, 912447414, 39868117, 'OR', 
    'b');
Insert into SCOTT.ACCOUNTS
   (ID, ACCOUNT_NUMBER, CUSTOMER_ID, BRANCH_ID, REGION, 
    STATUS)
 Values
   (1813999643, 1738970302, 98672809, 54100636, 'OR', 
    'M');
Insert into SCOTT.ACCOUNTS
   (ID, ACCOUNT_NUMBER, CUSTOMER_ID, BRANCH_ID, REGION, 
    STATUS)
 Values
   (60561891, 1229089094, 1626776049, 1373758116, 'OR', 
    'l');
Insert into SCOTT.ACCOUNTS
   (ID, ACCOUNT_NUMBER, CUSTOMER_ID, BRANCH_ID, REGION, 
    STATUS)
 Values
   (1194099877, 966075960, 973792659, 106417526, 'WA', 
    'E');
Insert into SCOTT.ACCOUNTS
   (ID, ACCOUNT_NUMBER, CUSTOMER_ID, BRANCH_ID, REGION, 
    STATUS)
 Values
   (972828393, 1964561103, 715385951, 581092182, 'AZ', 
    'f');
Insert into SCOTT.ACCOUNTS
   (ID, ACCOUNT_NUMBER, CUSTOMER_ID, BRANCH_ID, REGION, 
    STATUS)
 Values
   (1387745036, 811991623, 884849418, 924597781, 'AZ', 
    'B');
Insert into SCOTT.ACCOUNTS
   (ID, ACCOUNT_NUMBER, CUSTOMER_ID, BRANCH_ID, REGION, 
    STATUS)
 Values
   (4042014, 1008692733, 524884932, 755313715, 'NM', 
    'U');
Insert into SCOTT.ACCOUNTS
   (ID, ACCOUNT_NUMBER, CUSTOMER_ID, BRANCH_ID, REGION, 
    STATUS)
 Values
   (9035402, 85439893, 333606312, 233856899, 'UT', 
    'j');
Insert into SCOTT.ACCOUNTS
   (ID, ACCOUNT_NUMBER, CUSTOMER_ID, BRANCH_ID, REGION, 
    STATUS)
 Values
   (300439305, 809521660, 602721207, 1167124218, 'UT', 
    'C');
Insert into SCOTT.ACCOUNTS
   (ID, ACCOUNT_NUMBER, CUSTOMER_ID, BRANCH_ID, REGION, 
    STATUS)
 Values
   (1261574467, 1642196402, 1309279369, 811128713, 'AZ', 
    'Z');
Insert into SCOTT.ACCOUNTS
   (ID, ACCOUNT_NUMBER, CUSTOMER_ID, BRANCH_ID, REGION, 
    STATUS)
 Values
   (1734634260, 1893138191, 36547218, 1696588381, 'AZ', 
    'd');
Insert into SCOTT.ACCOUNTS
   (ID, ACCOUNT_NUMBER, CUSTOMER_ID, BRANCH_ID, REGION, 
    STATUS)
 Values
   (1393860542, 207139753, 1053973916, 2015424087, 'NM', 
    'L');
Insert into SCOTT.ACCOUNTS
   (ID, ACCOUNT_NUMBER, CUSTOMER_ID, BRANCH_ID, REGION, 
    STATUS)
 Values
   (1104007962, 703835058, 1058040433, 973595416, 'NM', 
    'X');
Insert into SCOTT.ACCOUNTS
   (ID, ACCOUNT_NUMBER, CUSTOMER_ID, BRANCH_ID, REGION, 
    STATUS)
 Values
   (1829413354, 1360120309, 475884296, 275389923, 'NM', 
    'o');
Insert into SCOTT.ACCOUNTS
   (ID, ACCOUNT_NUMBER, CUSTOMER_ID, BRANCH_ID, REGION, 
    STATUS)
 Values
   (644314976, 1910013550, 770148070, 1201992324, 'AZ', 
    'B');
Insert into SCOTT.ACCOUNTS
   (ID, ACCOUNT_NUMBER, CUSTOMER_ID, BRANCH_ID, REGION, 
    STATUS)
 Values
   (1479078753, 501738145, 2081089479, 1365686422, 'NM', 
    'H');
Insert into SCOTT.ACCOUNTS
   (ID, ACCOUNT_NUMBER, CUSTOMER_ID, BRANCH_ID, REGION, 
    STATUS)
 Values
   (340748485, 1276107083, 11726459, 1736071185, 'NM', 
    'k');
COMMIT;

查询分区中的数据

SQL> select count(*) from accounts;

  COUNT(*)
----------
	29

SQL> select count(*) from accounts partition(p_northwest); 

  COUNT(*)
----------
	16

SQL> select count(*) from accounts PARTITION (p_southwest);

  COUNT(*)
----------
	13

SQL> select count(*) from accounts PARTITION (p_northeast);

  COUNT(*)
----------
	 0

分区裁剪测试

SQL> set autotrace on
SQL> select count(*) from  accounts where REGION='AZ';

  COUNT(*)
----------
	 5


Execution Plan
----------------------------------------------------------
Plan hash value: 3505378

---------------------------------------------------------------------------------------------------
| Id  | Operation	       | Name	  | Rows  | Bytes | Cost (%CPU)| Time	  | Pstart| Pstop |
---------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |	  |	1 |	3 |    14   (0)| 00:00:01 |	  |	  |
|   1 |  SORT AGGREGATE        |	  |	1 |	3 |	       |	  |	  |	  |
|   2 |   PARTITION LIST SINGLE|	  |	5 |    15 |    14   (0)| 00:00:01 |   KEY |   KEY |
|*  3 |    TABLE ACCESS FULL   | ACCOUNTS |	5 |    15 |    14   (0)| 00:00:01 |	2 |	2 |
---------------------------------------------------------------------------------------------------

由执行计划中可以看出,Oracle只查询了一个分区的数据。


创建RANGE分区

CREATE TABLE SALES
(
  PROD_ID        NUMBER        NOT NULL,
  CUST_ID        NUMBER        NOT NULL,
  TIME_ID        DATE          NOT NULL,
  CHANNEL_ID     NUMBER        NOT NULL,
  PROMO_ID       NUMBER        NOT NULL,
  QUANTITY_SOLD  NUMBER(10,2)  NOT NULL,
  AMOUNT_SOLD    NUMBER(10,2)  NOT NULL
)
PARTITION BY RANGE (TIME_ID)
(    
  PARTITION SALES_Q1_2003 VALUES LESS THAN (TO_DATE('2003-04-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS')),
  PARTITION SALES_Q2_2003 VALUES LESS THAN (TO_DATE('2003-07-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS')) ,  
  PARTITION SALES_Q3_2003 VALUES LESS THAN (TO_DATE('2003-10-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS')),  
  PARTITION SALES_Q4_2003 VALUES LESS THAN (TO_DATE('2004-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS'))
);

11g新增了一个时间间隔分区,本质上是RANGE分区的一个扩展。

CREATE TABLE SALES2
(
  PROD_ID        NUMBER        NOT NULL,
  CUST_ID        NUMBER        NOT NULL,
  TIME_ID        DATE          NOT NULL,
  CHANNEL_ID     NUMBER        NOT NULL,
  PROMO_ID       NUMBER        NOT NULL,
  QUANTITY_SOLD  NUMBER(10,2)  NOT NULL,
  AMOUNT_SOLD    NUMBER(10,2)  NOT NULL
)
PARTITION BY RANGE (TIME_ID) INTERVAL(NUMTOYMINTERVAL(3,'MONTH'))
(    
  PARTITION SALES_Q1_2003 VALUES LESS THAN (TO_DATE('2003-04-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS'))
);

时间间隔分区会自动根据数据维护分区。我们做如下数据插入

SET DEFINE OFF;
Insert into SALES2
   (PROD_ID, CUST_ID, TIME_ID, CHANNEL_ID, PROMO_ID, 
    QUANTITY_SOLD, AMOUNT_SOLD)
 Values
   (15, 519, TO_DATE('01/25/2003 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 3, 999, 
    1, 1003.49);
Insert into SALES2
   (PROD_ID, CUST_ID, TIME_ID, CHANNEL_ID, PROMO_ID, 
    QUANTITY_SOLD, AMOUNT_SOLD)
 Values
   (32, 12824, TO_DATE('03/13/2003 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 3, 999, 
    1, 73.43);
Insert into SALES2
   (PROD_ID, CUST_ID, TIME_ID, CHANNEL_ID, PROMO_ID, 
    QUANTITY_SOLD, AMOUNT_SOLD)
 Values
   (47, 3289, TO_DATE('01/15/2003 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 4, 999, 
    1, 29.89);
Insert into SALES2
   (PROD_ID, CUST_ID, TIME_ID, CHANNEL_ID, PROMO_ID, 
    QUANTITY_SOLD, AMOUNT_SOLD)
 Values
   (116, 2945, TO_DATE('09/23/2003 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 3, 999, 
    1, 14.35);
Insert into SALES2
   (PROD_ID, CUST_ID, TIME_ID, CHANNEL_ID, PROMO_ID, 
    QUANTITY_SOLD, AMOUNT_SOLD)
 Values
   (48, 1580, TO_DATE('12/24/2003 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 3, 999, 
    1, 13.13);
Insert into SALES2
   (PROD_ID, CUST_ID, TIME_ID, CHANNEL_ID, PROMO_ID, 
    QUANTITY_SOLD, AMOUNT_SOLD)
 Values
   (19, 2671, TO_DATE('03/16/2003 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 4, 999, 
    1, 52.4);
Insert into SALES2
   (PROD_ID, CUST_ID, TIME_ID, CHANNEL_ID, PROMO_ID, 
    QUANTITY_SOLD, AMOUNT_SOLD)
 Values
   (142, 6834, TO_DATE('02/02/2003 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 3, 999, 
    1, 25.4);
Insert into SALES2
   (PROD_ID, CUST_ID, TIME_ID, CHANNEL_ID, PROMO_ID, 
    QUANTITY_SOLD, AMOUNT_SOLD)
 Values
   (33, 5579, TO_DATE('07/23/2003 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 2, 999, 
    1, 45.71);
Insert into SALES2
   (PROD_ID, CUST_ID, TIME_ID, CHANNEL_ID, PROMO_ID, 
    QUANTITY_SOLD, AMOUNT_SOLD)
 Values
   (35, 10985, TO_DATE('08/20/2003 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 3, 999, 
    1, 59.78);
Insert into SALES2
   (PROD_ID, CUST_ID, TIME_ID, CHANNEL_ID, PROMO_ID, 
    QUANTITY_SOLD, AMOUNT_SOLD)
 Values
   (28, 13125, TO_DATE('10/13/2003 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 2, 999, 
    1, 203.18);
Insert into SALES2
   (PROD_ID, CUST_ID, TIME_ID, CHANNEL_ID, PROMO_ID, 
    QUANTITY_SOLD, AMOUNT_SOLD)
 Values
   (46, 6719, TO_DATE('10/10/2003 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 3, 999, 
    1, 25.83);
Insert into SALES2
   (PROD_ID, CUST_ID, TIME_ID, CHANNEL_ID, PROMO_ID, 
    QUANTITY_SOLD, AMOUNT_SOLD)
 Values
   (23, 33729, TO_DATE('01/16/2003 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 2, 999, 
    1, 23.51);
Insert into SALES2
   (PROD_ID, CUST_ID, TIME_ID, CHANNEL_ID, PROMO_ID, 
    QUANTITY_SOLD, AMOUNT_SOLD)
 Values
   (23, 9927, TO_DATE('03/28/2003 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 3, 999, 
    1, 23.19);
Insert into SALES2
   (PROD_ID, CUST_ID, TIME_ID, CHANNEL_ID, PROMO_ID, 
    QUANTITY_SOLD, AMOUNT_SOLD)
 Values
   (118, 818, TO_DATE('01/24/2003 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 2, 999, 
    1, 8.86);
Insert into SALES2
   (PROD_ID, CUST_ID, TIME_ID, CHANNEL_ID, PROMO_ID, 
    QUANTITY_SOLD, AMOUNT_SOLD)
 Values
   (135, 5860, TO_DATE('02/27/2003 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 3, 999, 
    1, 55.43);
Insert into SALES2
   (PROD_ID, CUST_ID, TIME_ID, CHANNEL_ID, PROMO_ID, 
    QUANTITY_SOLD, AMOUNT_SOLD)
 Values
   (41, 2292, TO_DATE('04/13/2003 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 2, 999, 
    1, 48.78);
Insert into SALES2
   (PROD_ID, CUST_ID, TIME_ID, CHANNEL_ID, PROMO_ID, 
    QUANTITY_SOLD, AMOUNT_SOLD)
 Values
   (30, 7859, TO_DATE('07/14/2003 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 3, 999, 
    1, 10.48);
Insert into SALES2
   (PROD_ID, CUST_ID, TIME_ID, CHANNEL_ID, PROMO_ID, 
    QUANTITY_SOLD, AMOUNT_SOLD)
 Values
   (128, 3266, TO_DATE('07/15/2003 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 3, 999, 
    1, 30.07);
Insert into SALES2
   (PROD_ID, CUST_ID, TIME_ID, CHANNEL_ID, PROMO_ID, 
    QUANTITY_SOLD, AMOUNT_SOLD)
 Values
   (145, 3461, TO_DATE('10/27/2003 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 3, 999, 
    1, 13.76);
Insert into SALES2
   (PROD_ID, CUST_ID, TIME_ID, CHANNEL_ID, PROMO_ID, 
    QUANTITY_SOLD, AMOUNT_SOLD)
 Values
   (24, 9170, TO_DATE('02/07/2003 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 3, 351, 
    1, 63.97);
Insert into SALES2
   (PROD_ID, CUST_ID, TIME_ID, CHANNEL_ID, PROMO_ID, 
    QUANTITY_SOLD, AMOUNT_SOLD)
 Values
   (118, 1156, TO_DATE('01/29/2003 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 4, 999, 
    1, 17.53);
Insert into SALES2
   (PROD_ID, CUST_ID, TIME_ID, CHANNEL_ID, PROMO_ID, 
    QUANTITY_SOLD, AMOUNT_SOLD)
 Values
   (26, 11267, TO_DATE('06/10/2003 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 2, 999, 
    1, 156.71);
Insert into SALES2
   (PROD_ID, CUST_ID, TIME_ID, CHANNEL_ID, PROMO_ID, 
    QUANTITY_SOLD, AMOUNT_SOLD)
 Values
   (31, 8630, TO_DATE('04/02/2003 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 3, 999, 
    1, 8.95);
Insert into SALES2
   (PROD_ID, CUST_ID, TIME_ID, CHANNEL_ID, PROMO_ID, 
    QUANTITY_SOLD, AMOUNT_SOLD)
 Values
   (23, 392, TO_DATE('08/30/2003 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 4, 999, 
    1, 21.22);
Insert into SALES2
   (PROD_ID, CUST_ID, TIME_ID, CHANNEL_ID, PROMO_ID, 
    QUANTITY_SOLD, AMOUNT_SOLD)
 Values
   (47, 280, TO_DATE('08/13/2003 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 2, 999, 
    1, 29.02);
Insert into SALES2
   (PROD_ID, CUST_ID, TIME_ID, CHANNEL_ID, PROMO_ID, 
    QUANTITY_SOLD, AMOUNT_SOLD)
 Values
   (119, 6822, TO_DATE('08/06/2003 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), 3, 999, 
    1, 7.31);
COMMIT;

现在我们查看sales2的分区情况

SQL> SELECT TABLE_NAME, PARTITION_NAME
      FROM dba_tab_partitions
    WHERE TABLE_OWNER = 'SCOTT' AND TABLE_NAME = 'SALES2';

TABLE_NAME		       PARTITION_NAME
------------------------------ ------------------------------
SALES2			       SALES_Q1_2003
SALES2			       SYS_P41
SALES2			       SYS_P42
SALES2			       SYS_P43

可见系统根据数据的实际情况,给我们新建了3个分区,分区由系统自命名。

创建HASH分区

CREATE TABLE sales_hash
  (s_productid  NUMBER,
   s_saledate   DATE,
   s_custid     NUMBER,
   s_totalprice NUMBER)
PARTITION BY HASH(s_productid)
( PARTITION p1 TABLESPACE users
, PARTITION p2 TABLESPACE users
, PARTITION p3 TABLESPACE users
, PARTITION p4 TABLESPACE users
);

根据s_productionid的值,算出hash值,将对于的数据行插入到相应的分区中。各分区数据要想分别均匀,分区的个数为2的次方数。

创建SYSTEM分区

此分区与其他的都不同,数据插入到哪个分区与数据本身无关,完全有用户自定义。

CREATE TABLE t_system
(
   id     NUMBER,
   name   VARCHAR2 (30)
)
PARTITION BY SYSTEM 
(PARTITION p1, PARTITION p2, PARTITION p3, PARTITION p4);

此时往表中直接插入数据就会报错

SQL> insert into t_system(id,name)values(1,'kevin');
insert into t_system(id,name)values(1,'kevin')
            *
ERROR at line 1:
ORA-14701: partition-extended name or bind variable must be used for DMLs on tables partitioned by the System method

插入数据,必须指定分区名称

SQL> insert into t_system partition(p1)(id,name)values(1,'kevin');

1 row created.

并且重复数据可以插入到不同的分区

SQL>  insert into t_system partition(p2)(id,name)values(1,'kevin');
1 row created.


创建虚拟列分区

Oracle11g新增了虚拟列功能,虚拟列的值从其他的列推导而来,Oracle只保存源数据,这个列不占存储空间。虚拟列其中一个引申功能就是虚拟列分区功能。11g增加对虚拟列的支持,这使得分区功能更加灵活。如:表中有一个日期列,希望根据日期列进行分区,每个月份一个分区,总共12个分区,不管是哪一年的,只要是那个月,就放在那个月的分区中。

CREATE TABLE T_PARTITION_MONTH
(
   ID                NUMBER,
   NAME              VARCHAR2 (30),
   CREATE_DATE       DATE,
   PARTITION_MONTH   AS (TO_NUMBER (TO_CHAR (CREATE_DATE, 'MM')))
)
PARTITION BY LIST
   (PARTITION_MONTH)
   (
      PARTITION P1 VALUES (1),
      PARTITION P2 VALUES (2),
      PARTITION P3 VALUES (3),
      PARTITION P4 VALUES (4),
      PARTITION P5 VALUES (5),
      PARTITION P6 VALUES (6),
      PARTITION P7 VALUES (7),
      PARTITION P8 VALUES (8),
      PARTITION P9 VALUES (9),
      PARTITION P10 VALUES (10),
      PARTITION P11 VALUES (11),
      PARTITION P12 VALUES (12));

创建参考列分区

子表的分区依赖于父表,我们看如下例子

CREATE TABLE orders
    ( order_id           NUMBER(12),
      order_date         TIMESTAMP,
      order_mode         VARCHAR2(8),
      customer_id        NUMBER(6),
      order_status       NUMBER(2),
      order_total        NUMBER(8,2),
      sales_rep_id       NUMBER(6),
      promotion_id       NUMBER(6),
      CONSTRAINT orders_pk PRIMARY KEY(order_id)
    )
  PARTITION BY RANGE(order_date)
    ( PARTITION Q1_2005 VALUES LESS THAN (TO_DATE('01-APR-2005','DD-MON-YYYY')),
      PARTITION Q2_2005 VALUES LESS THAN (TO_DATE('01-JUL-2005','DD-MON-YYYY')),
      PARTITION Q3_2005 VALUES LESS THAN (TO_DATE('01-OCT-2005','DD-MON-YYYY')),
      PARTITION Q4_2005 VALUES LESS THAN (TO_DATE('01-JAN-2006','DD-MON-YYYY'))
    );

订单表,按order_date做范围分区。

CREATE TABLE order_items
    ( order_id           NUMBER(12) NOT NULL,
      line_item_id       NUMBER(3)  NOT NULL,
      product_id         NUMBER(6)  NOT NULL,
      unit_price         NUMBER(8,2),
      quantity           NUMBER(8),
      CONSTRAINT order_items_fk
      FOREIGN KEY(order_id) REFERENCES orders(order_id)
    )
    PARTITION BY REFERENCE(order_items_fk);

订单项目表,该表分区参考主表。

查看order_items的分区信息

SQL> SELECT TABLE_NAME, PARTITION_NAME
  FROM DBA_TAB_PARTITIONS
 WHERE TABLE_NAME = 'ORDER_ITEMS';

TABLE_NAME		       PARTITION_NAME
------------------------------ ------------------------------
ORDER_ITEMS		       Q1_2005
ORDER_ITEMS		       Q2_2005
ORDER_ITEMS		       Q3_2005
ORDER_ITEMS		       Q4_2005

对于range和hash分区,你可以指定多列作为分区键。列数最多16个。

CREATE TABLE sales_demo (
   year          NUMBER, 
   month         NUMBER,
   day           NUMBER,
   amount_sold   NUMBER) 
PARTITION BY RANGE (year,month) 
  (PARTITION before2001 VALUES LESS THAN (2001,1),
   PARTITION q1_2001    VALUES LESS THAN (2001,4),
   PARTITION q2_2001    VALUES LESS THAN (2001,7),
   PARTITION q3_2001    VALUES LESS THAN (2001,10),
   PARTITION q4_2001    VALUES LESS THAN (2002,1),
   PARTITION future     VALUES LESS THAN (MAXVALUE,0));

REM  12-DEC-2000
INSERT INTO sales_demo VALUES(2000,12,12, 1000);
REM  17-MAR-2001
INSERT INTO sales_demo VALUES(2001,3,17, 2000);
REM  1-NOV-2001
INSERT INTO sales_demo VALUES(2001,11,1, 5000);
REM  1-JAN-2002
INSERT INTO sales_demo VALUES(2002,1,1, 4000);



组合分区有如下六种:

RANGE-RANGE、RANGE-LIST、RANGE-HASH、LIST-RANGE、LIST-LIST、LIST-HASH 。

组合分区的创建与单分区类似。

创建RANGE-RANGE组合分区

CREATE TABLE shipments
( order_id      NUMBER NOT NULL
, order_date    DATE NOT NULL
, delivery_date DATE NOT NULL
, customer_id   NUMBER NOT NULL
, sales_amount  NUMBER NOT NULL
)
PARTITION BY RANGE (order_date)
SUBPARTITION BY RANGE (delivery_date)
( PARTITION p_2006_jul VALUES LESS THAN (TO_DATE('01-AUG-2006','dd-MON-yyyy'))
  ( SUBPARTITION p06_jul_e VALUES LESS THAN (TO_DATE('15-AUG-2006','dd-MON-yyyy'))
  , SUBPARTITION p06_jul_a VALUES LESS THAN (TO_DATE('01-SEP-2006','dd-MON-yyyy'))
  , SUBPARTITION p06_jul_l VALUES LESS THAN (MAXVALUE)
  )
, PARTITION p_2006_aug VALUES LESS THAN (TO_DATE('01-SEP-2006','dd-MON-yyyy'))
  ( SUBPARTITION p06_aug_e VALUES LESS THAN (TO_DATE('15-SEP-2006','dd-MON-yyyy'))
  , SUBPARTITION p06_aug_a VALUES LESS THAN (TO_DATE('01-OCT-2006','dd-MON-yyyy'))
  , SUBPARTITION p06_aug_l VALUES LESS THAN (MAXVALUE)
  )
, PARTITION p_2006_sep VALUES LESS THAN (TO_DATE('01-OCT-2006','dd-MON-yyyy'))
  ( SUBPARTITION p06_sep_e VALUES LESS THAN (TO_DATE('15-OCT-2006','dd-MON-yyyy'))
  , SUBPARTITION p06_sep_a VALUES LESS THAN (TO_DATE('01-NOV-2006','dd-MON-yyyy'))
  , SUBPARTITION p06_sep_l VALUES LESS THAN (MAXVALUE)
  )
, PARTITION p_2006_oct VALUES LESS THAN (TO_DATE('01-NOV-2006','dd-MON-yyyy'))
  ( SUBPARTITION p06_oct_e VALUES LESS THAN (TO_DATE('15-NOV-2006','dd-MON-yyyy'))
  , SUBPARTITION p06_oct_a VALUES LESS THAN (TO_DATE('01-DEC-2006','dd-MON-yyyy'))
  , SUBPARTITION p06_oct_l VALUES LESS THAN (MAXVALUE)
  )
, PARTITION p_2006_nov VALUES LESS THAN (TO_DATE('01-DEC-2006','dd-MON-yyyy'))
  ( SUBPARTITION p06_nov_e VALUES LESS THAN (TO_DATE('15-DEC-2006','dd-MON-yyyy'))
  , SUBPARTITION p06_nov_a VALUES LESS THAN (TO_DATE('01-JAN-2007','dd-MON-yyyy'))
  , SUBPARTITION p06_nov_l VALUES LESS THAN (MAXVALUE)
  )
, PARTITION p_2006_dec VALUES LESS THAN (TO_DATE('01-JAN-2007','dd-MON-yyyy'))
  ( SUBPARTITION p06_dec_e VALUES LESS THAN (TO_DATE('15-JAN-2007','dd-MON-yyyy'))
  , SUBPARTITION p06_dec_a VALUES LESS THAN (TO_DATE('01-FEB-2007','dd-MON-yyyy'))
  , SUBPARTITION p06_dec_l VALUES LESS THAN (MAXVALUE)
  )
);

查看分区信息

SQL> SELECT TABLE_NAME, PARTITION_NAME,SUBPARTITION_COUNT
  FROM DBA_TAB_PARTITIONS
 WHERE TABLE_NAME = 'SHIPMENTS';   

TABLE_NAME		       PARTITION_NAME		      SUBPARTITION_COUNT
------------------------------ ------------------------------ ------------------
SHIPMENTS		       P_2006_JUL				       3
SHIPMENTS		       P_2006_AUG				       3
SHIPMENTS		       P_2006_SEP				       3
SHIPMENTS		       P_2006_OCT				       3
SHIPMENTS		       P_2006_NOV				       3
SHIPMENTS		       P_2006_DEC				       3

6 rows selected.

查看子分区信息

SQL>  SELECT TABLE_NAME, PARTITION_NAME,SUBPARTITION_NAME
   FROM DBA_TAB_SUBPARTITIONS
 WHERE TABLE_NAME = 'SHIPMENTS'; 

TABLE_NAME		       PARTITION_NAME		      SUBPARTITION_NAME
------------------------------ ------------------------------ ------------------------------
SHIPMENTS		       P_2006_DEC		      P06_DEC_E
SHIPMENTS		       P_2006_DEC		      P06_DEC_A
SHIPMENTS		       P_2006_DEC		      P06_DEC_L
SHIPMENTS		       P_2006_NOV		      P06_NOV_E
SHIPMENTS		       P_2006_NOV		      P06_NOV_A
SHIPMENTS		       P_2006_NOV		      P06_NOV_L
SHIPMENTS		       P_2006_OCT		      P06_OCT_E
SHIPMENTS		       P_2006_OCT		      P06_OCT_A
SHIPMENTS		       P_2006_OCT		      P06_OCT_L
SHIPMENTS		       P_2006_SEP		      P06_SEP_E
SHIPMENTS		       P_2006_SEP		      P06_SEP_A

TABLE_NAME		       PARTITION_NAME		      SUBPARTITION_NAME
------------------------------ ------------------------------ ------------------------------
SHIPMENTS		       P_2006_SEP		      P06_SEP_L
SHIPMENTS		       P_2006_AUG		      P06_AUG_E
SHIPMENTS		       P_2006_AUG		      P06_AUG_A
SHIPMENTS		       P_2006_AUG		      P06_AUG_L
SHIPMENTS		       P_2006_JUL		      P06_JUL_E
SHIPMENTS		       P_2006_JUL		      P06_JUL_A
SHIPMENTS		       P_2006_JUL		      P06_JUL_L

18 rows selected.


创建RANGE-LIST

CREATE TABLE quarterly_regional_sales
      (deptno number, item_no varchar2(20),
       txn_date date, txn_amount number, state varchar2(2))
  TABLESPACE ts4
  PARTITION BY RANGE (txn_date)
    SUBPARTITION BY LIST (state)
      (PARTITION q1_1999 VALUES LESS THAN (TO_DATE('1-APR-1999','DD-MON-YYYY'))
         (SUBPARTITION q1_1999_northwest VALUES ('OR', 'WA'),
          SUBPARTITION q1_1999_southwest VALUES ('AZ', 'UT', 'NM'),
          SUBPARTITION q1_1999_northeast VALUES ('NY', 'VM', 'NJ'),
          SUBPARTITION q1_1999_southeast VALUES ('FL', 'GA'),
          SUBPARTITION q1_1999_northcentral VALUES ('SD', 'WI'),
          SUBPARTITION q1_1999_southcentral VALUES ('OK', 'TX')
         ),
       PARTITION q2_1999 VALUES LESS THAN ( TO_DATE('1-JUL-1999','DD-MON-YYYY'))
         (SUBPARTITION q2_1999_northwest VALUES ('OR', 'WA'),
          SUBPARTITION q2_1999_southwest VALUES ('AZ', 'UT', 'NM'),
          SUBPARTITION q2_1999_northeast VALUES ('NY', 'VM', 'NJ'),
          SUBPARTITION q2_1999_southeast VALUES ('FL', 'GA'),
          SUBPARTITION q2_1999_northcentral VALUES ('SD', 'WI'),
          SUBPARTITION q2_1999_southcentral VALUES ('OK', 'TX')
         ),
       PARTITION q3_1999 VALUES LESS THAN (TO_DATE('1-OCT-1999','DD-MON-YYYY'))
         (SUBPARTITION q3_1999_northwest VALUES ('OR', 'WA'),
          SUBPARTITION q3_1999_southwest VALUES ('AZ', 'UT', 'NM'),
          SUBPARTITION q3_1999_northeast VALUES ('NY', 'VM', 'NJ'),
          SUBPARTITION q3_1999_southeast VALUES ('FL', 'GA'),
          SUBPARTITION q3_1999_northcentral VALUES ('SD', 'WI'),
          SUBPARTITION q3_1999_southcentral VALUES ('OK', 'TX')
         ),
       PARTITION q4_1999 VALUES LESS THAN ( TO_DATE('1-JAN-2000','DD-MON-YYYY'))
         (SUBPARTITION q4_1999_northwest VALUES ('OR', 'WA'),
          SUBPARTITION q4_1999_southwest VALUES ('AZ', 'UT', 'NM'),
          SUBPARTITION q4_1999_northeast VALUES ('NY', 'VM', 'NJ'),
          SUBPARTITION q4_1999_southeast VALUES ('FL', 'GA'),
          SUBPARTITION q4_1999_northcentral VALUES ('SD', 'WI'),
          SUBPARTITION q4_1999_southcentral VALUES ('OK', 'TX')
         )
      );


创建RANGE-HASH分区

CREATE TABLE sales
  ( prod_id       NUMBER(6)
  , cust_id       NUMBER
  , time_id       DATE
  , channel_id    CHAR(1)
  , promo_id      NUMBER(6)
  , quantity_sold NUMBER(3)
  , amount_sold   NUMBER(10,2)
  )
 PARTITION BY RANGE (time_id) SUBPARTITION BY HASH (cust_id)
  SUBPARTITIONS 8 STORE IN (ts1, ts2, ts3, ts4)
 ( PARTITION sales_q1_2006 VALUES LESS THAN (TO_DATE('01-APR-2006','dd-MON-yyyy'))
 , PARTITION sales_q2_2006 VALUES LESS THAN (TO_DATE('01-JUL-2006','dd-MON-yyyy'))
 , PARTITION sales_q3_2006 VALUES LESS THAN (TO_DATE('01-OCT-2006','dd-MON-yyyy'))
 , PARTITION sales_q4_2006 VALUES LESS THAN (TO_DATE('01-JAN-2007','dd-MON-yyyy'))
 );

子分区也可以指定模板

如下:

CREATE TABLE sales_range_range
  ( prod_id       NUMBER(6)
  , cust_id       NUMBER
  , time_id       DATE
  , channel_id    CHAR(1)
  , promo_id      NUMBER(6)
  , quantity_sold NUMBER(3)
  , amount_sold   NUMBER(10,2)
  )
 PARTITION BY RANGE (time_id) INTERVAL (NUMTODSINTERVAL(1,'DAY'))
SUBPARTITION BY RANGE(amount_sold)
   SUBPARTITION TEMPLATE
   ( SUBPARTITION p_low VALUES LESS THAN (1000)
   , SUBPARTITION p_medium VALUES LESS THAN (4000)
   , SUBPARTITION p_high VALUES LESS THAN (8000)
   , SUBPARTITION p_ultimate VALUES LESS THAN (maxvalue)
   )
 ( PARTITION before_2000 VALUES LESS THAN (TO_DATE('01-JAN-2000','dd-MON-yyyy')))
或者
CREATE TABLE sales_range_range
  ( prod_id       NUMBER(6)
  , cust_id       NUMBER
  , time_id       DATE
  , channel_id    CHAR(1)
  , promo_id      NUMBER(6)
  , quantity_sold NUMBER(3)
  , amount_sold   NUMBER(10,2)
  )
 PARTITION BY RANGE (time_id)
SUBPARTITION BY RANGE(amount_sold)
   SUBPARTITION TEMPLATE
   ( SUBPARTITION p_low VALUES LESS THAN (1000)
   , SUBPARTITION p_medium VALUES LESS THAN (4000)
   , SUBPARTITION p_high VALUES LESS THAN (8000)
   , SUBPARTITION p_ultimate VALUES LESS THAN (maxvalue)
   )
 ( PARTITION before_2000 VALUES LESS THAN (TO_DATE('01-JAN-2000','dd-MON-yyyy')))
CREATE TABLE emp_sub_template (deptno NUMBER, empname VARCHAR(32), grade NUMBER)
     PARTITION BY RANGE(deptno) SUBPARTITION BY HASH(empname)
     SUBPARTITION TEMPLATE
         (SUBPARTITION a TABLESPACE ts1,
          SUBPARTITION b TABLESPACE ts2,
          SUBPARTITION c TABLESPACE ts3,
          SUBPARTITION d TABLESPACE ts4
         )
    (PARTITION p1 VALUES LESS THAN (1000),
     PARTITION p2 VALUES LESS THAN (2000),
     PARTITION p3 VALUES LESS THAN (MAXVALUE)
    );
CREATE TABLE stripe_regional_sales
            ( deptno number, item_no varchar2(20),
              txn_date date, txn_amount number, state varchar2(2))
   PARTITION BY RANGE (txn_date)
   SUBPARTITION BY LIST (state)
   SUBPARTITION TEMPLATE 
      (SUBPARTITION northwest VALUES ('OR', 'WA') TABLESPACE tbs_1,
       SUBPARTITION southwest VALUES ('AZ', 'UT', 'NM') TABLESPACE tbs_2,
       SUBPARTITION northeast VALUES ('NY', 'VM', 'NJ') TABLESPACE tbs_3,
       SUBPARTITION southeast VALUES ('FL', 'GA') TABLESPACE tbs_4,
       SUBPARTITION midwest VALUES ('SD', 'WI') TABLESPACE tbs_5,
       SUBPARTITION south VALUES ('AL', 'AK') TABLESPACE tbs_6,
       SUBPARTITION others VALUES (DEFAULT ) TABLESPACE tbs_7
      )
  (PARTITION q1_1999 VALUES LESS THAN ( TO_DATE('01-APR-1999','DD-MON-YYYY')),
   PARTITION q2_1999 VALUES LESS THAN ( TO_DATE('01-JUL-1999','DD-MON-YYYY')),
   PARTITION q3_1999 VALUES LESS THAN ( TO_DATE('01-OCT-1999','DD-MON-YYYY')),
   PARTITION q4_1999 VALUES LESS THAN ( TO_DATE('1-JAN-2000','DD-MON-YYYY'))
  );


创建分区索引

本地索引

SQL> create index idx_accounts_number on accounts(account_number) local;

Index created.

创建索引时,添加local关键字,即为表的每个分区单独创建一个索引。

SQL> select index_name,partition_name from dba_ind_partitions where index_name='IDX_ACCOUNTS_NUMBER';

INDEX_NAME		       PARTITION_NAME
------------------------------ ------------------------------
IDX_ACCOUNTS_NUMBER	       P_NORTHCENTRAL
IDX_ACCOUNTS_NUMBER	       P_NORTHEAST
IDX_ACCOUNTS_NUMBER	       P_NORTHWEST
IDX_ACCOUNTS_NUMBER	       P_SOUTHCENTRAL
IDX_ACCOUNTS_NUMBER	       P_SOUTHEAST
IDX_ACCOUNTS_NUMBER	       P_SOUTHWEST

6 rows selected.

可见,表有几个分区,就创建几个索引分区。


全局索引

创建方法与普通索引一致。

SQL> create index idx_accounts_id on accounts(id);

Index created.
SQL> select index_name,partition_name from dba_ind_partitions where index_name='IDX_ACCOUNTS_ID';

no rows selected

索引没有分区。

全局分区索引

SQL> create index idx_accounts_customer_id 
     on accounts(customer_id) 
     global partition by hash(customer_id)
     partitions 4;

Index created.
SQL>  select index_name,partition_name from dba_ind_partitions where index_name='IDX_ACCOUNTS_CUSTOMER_ID';

INDEX_NAME		       PARTITION_NAME
------------------------------ ------------------------------
IDX_ACCOUNTS_CUSTOMER_ID       SYS_P61
IDX_ACCOUNTS_CUSTOMER_ID       SYS_P62
IDX_ACCOUNTS_CUSTOMER_ID       SYS_P63
IDX_ACCOUNTS_CUSTOMER_ID       SYS_P64


三、维护分区

添加分区

LIST分区

SQL> ALTER TABLE accounts
   ADD PARTITION p_nonmainland VALUES ('HI', 'PR');  

Table altered.

SQL>

RANGE分区

SQL> ALTER TABLE sales
   ADD PARTITION sale_q1_2004
      VALUES LESS THAN (TO_DATE ('2004-04-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS'));
Table altered.

SQL>

HASH分区

SQL> ALTER TABLE sales_hash ADD PARTITION; 

Table altered.

对于组合分区

SQL> ALTER TABLE shipments
   ADD PARTITION p_2007_jan
      VALUES LESS THAN (TO_DATE('01-FEB-2007','dd-MON-yyyy'));

Table altered.

如果添加分区时,不指定子分区,那么系统默认帮你建立一个子分区

SQL>  SELECT TABLE_NAME, PARTITION_NAME,SUBPARTITION_NAME
   FROM DBA_TAB_SUBPARTITIONS
 WHERE TABLE_NAME = 'SHIPMENTS' and PARTITION_NAME='P_2007_JAN';

TABLE_NAME		       PARTITION_NAME		      SUBPARTITION_NAME
------------------------------ ------------------------------ ------------------------------
SHIPMENTS		       P_2007_JAN		      SYS_SUBP82

添加分区时,也可以指定子分区

SQL> ALTER TABLE shipments
   ADD PARTITION p_2008_jan
      VALUES LESS THAN (TO_DATE('01-FEB-2008','dd-MON-yyyy')) 
      ( SUBPARTITION p07_jan_e VALUES LESS THAN (TO_DATE('15-FEB-2007','dd-MON-yyyy'))
      , SUBPARTITION p07_jan_a VALUES LESS THAN (TO_DATE('01-MAR-2007','dd-MON-yyyy'))
      , SUBPARTITION p07_jan_l VALUES LESS THAN (TO_DATE('01-APR-2007','dd-MON-yyyy'))
      ) ; 

Table altered.

此时子分区信息如下

SQL>  SELECT TABLE_NAME, PARTITION_NAME,SUBPARTITION_NAME
   FROM DBA_TAB_SUBPARTITIONS
 WHERE TABLE_NAME = 'SHIPMENTS' and PARTITION_NAME='P_2008_JAN';  

TABLE_NAME		       PARTITION_NAME		      SUBPARTITION_NAME
------------------------------ ------------------------------ ------------------------------
SHIPMENTS		       P_2008_JAN		      P07_JAN_E
SHIPMENTS		       P_2008_JAN		      P07_JAN_A
SHIPMENTS		       P_2008_JAN		      P07_JAN_L

如果组合分区的子分区指定了模板,那么添加分区时,无需指定子分区。

SQL> ALTER TABLE SALES_RANGE_RANGE
   ADD PARTITION P_2000
      VALUES LESS THAN (TO_DATE ('01-JAN-2001', 'dd-MON-yyyy'));  

Table altered.

查看分区信息

SQL>  SELECT TABLE_NAME, PARTITION_NAME,SUBPARTITION_NAME
   FROM DBA_TAB_SUBPARTITIONS
 WHERE TABLE_NAME = 'SALES_RANGE_RANGE' and PARTITION_NAME='P_2000'; 

TABLE_NAME		       PARTITION_NAME		      SUBPARTITION_NAME
------------------------------ ------------------------------ ------------------------------
SALES_RANGE_RANGE	       P_2000			      P_2000_P_LOW
SALES_RANGE_RANGE	       P_2000			      P_2000_P_MEDIUM
SALES_RANGE_RANGE	       P_2000			      P_2000_P_HIGH
SALES_RANGE_RANGE	       P_2000			      P_2000_P_ULTIMATE

删除分区

Use one of the following statements to drop a table partition or subpartition:

  • ALTER TABLE ... DROP PARTITION to drop a table partition

  • ALTER TABLE ... DROP SUBPARTITION to drop a subpartition of a composite *-[range | list] partitioned table

SQL> ALTER TABLE SALES DROP PARTITION SALE_Q1_2004; 

Table altered.

删除子分区

SQL> alter table sales_range_range drop subpartition P_2000_P_LOW;

Table altered.

hash分区是不能被删除的

SQL> ALTER TABLE SALES_HASH DROP PARTITION SYS_P81;
ALTER TABLE SALES_HASH DROP PARTITION SYS_P81
                                      *
ERROR at line 1:
ORA-14255: table is not partitioned by Range, List, Composite Range or Composite List method

hash分区需要使用COALESCE关键字合并分区

SQL> SELECT TABLE_NAME, PARTITION_NAME,SUBPARTITION_COUNT
  FROM DBA_TAB_PARTITIONS
 WHERE TABLE_NAME = 'SALES_HASH';  2    3  

TABLE_NAME		       PARTITION_NAME		      SUBPARTITION_COUNT
------------------------------ ------------------------------ ------------------
SALES_HASH		       P1					       0
SALES_HASH		       P2					       0
SALES_HASH		       P3					       0
SALES_HASH		       P4					       0
SALES_HASH		       SYS_P81					       0

SQL> ALTER TABLE SALES_HASH COALESCE PARTITION;

Table altered.

SQL> SELECT TABLE_NAME, PARTITION_NAME,SUBPARTITION_COUNT
  FROM DBA_TAB_PARTITIONS
 WHERE TABLE_NAME = 'SALES_HASH';  2    3  

TABLE_NAME		       PARTITION_NAME		      SUBPARTITION_COUNT
------------------------------ ------------------------------ ------------------
SALES_HASH		       P1					       0
SALES_HASH		       P2					       0
SALES_HASH		       P3					       0
SALES_HASH		       P4					       0

删除hash子分区用如下语法

ALTER TABLE diving MODIFY PARTITION us_locations
     COALESCE SUBPARTITION;


分区交换

exchange partition是用来将分区表与普通表之间做转换。但是普通表只能和分区表中的某个分区做交换。而不能简单的将普通表变成分区表。

CREATE TABLE t
(
   empno   NUMBER,
   sal     NUMBER
)
PARTITION BY RANGE
   (sal)
   (
      PARTITION sal_less_3000 VALUES LESS THAN (3000),
      PARTITION sal_between_3000_5000 VALUES LESS THAN (5000));

生成两个普通表

SQL> create table t_part1 as select empno,sal from emp where sal<3000;

Table created.

SQL>  create table t_part2 as select empno,sal from emp where sal>=3000 and sal<5000;

Table created.

查看表的data_object_id

SQL> COL OBJECT_NAME FOR A30
SQL> COL SUBOBJECT_NAME FOR A30
SQL> select OBJECT_NAME,SUBOBJECT_NAME,OBJECT_ID,DATA_OBJECT_ID from dba_objects where object_name in ('T','T_PART1','T_PART2');

OBJECT_NAME		       SUBOBJECT_NAME		       OBJECT_ID DATA_OBJECT_ID
------------------------------ ------------------------------ ---------- --------------
T			       SAL_LESS_3000			   88777	  88777
T								   88776
T_PART2 							   88775	  88775
T_PART1 							   88774	  88774
T			       SAL_BETWEEN_3000_5000		   88778	  88778

进行分区交换

SQL>  alter table t exchange partition sal_less_3000 with table t_part1;

Table altered.

SQL> alter table t exchange partition sal_between_3000_5000 with table t_part2;

Table altered.

SQL> select count(*) from t;

  COUNT(*)
----------
	26

再次查看data_object_id

SQL> select OBJECT_NAME,SUBOBJECT_NAME,OBJECT_ID,DATA_OBJECT_ID from dba_objects where object_name in ('T','T_PART1','T_PART2');

OBJECT_NAME		       SUBOBJECT_NAME		       OBJECT_ID DATA_OBJECT_ID
------------------------------ ------------------------------ ---------- --------------
T			       SAL_LESS_3000			   88777	  88774
T								   88776
T_PART2 							   88775	  88778
T_PART1 							   88774	  88777
T			       SAL_BETWEEN_3000_5000		   88778	  88775

可见t_part1、t_part2的data_object_id与分区的值发生了对调。交换分区执行修改了数据字典的内容。效率非常高。

子分区也可以发生交换,请参考官方文档。


分区合并

将两个分区合并成一个分区,hash分区例外

SQL> alter table accounts merge partitions p_northcentral ,p_southcentral into partition p_central;

Table altered.

如果是interval分区,可以使用如下语法

ALTER TABLE transactions
MERGE PARTITIONS FOR(TO_DATE('15-JAN-2007','dd-MON-yyyy'))
, FOR(TO_DATE('16-JAN-2007','dd-MON-yyyy'));

分区拆分

LIST分区

ALTER TABLE sales_by_region 
   SPLIT PARTITION region_east VALUES ('CT', 'MA', 'MD') 
   INTO 
    ( PARTITION region_east_1 
         TABLESPACE tbs2,
      PARTITION region_east_2
        STORAGE (INITIAL 8M)) 
   PARALLEL 5;

The literal value list for the original region_east partition was specified as:

PARTITION region_east VALUES ('MA','NY','CT','NH','ME','MD','VA','PA','NJ')

The two new partitions are:

  • region_east_1 with a literal value list of ('CT','MA','MD')

  • region_east_2 inheriting the remaining literal value list of ('NY','NH','ME','VA','PA','NJ')


范围分区

ALTER TABLE vet_cats SPLIT PARTITION 
      fee_katy at (100) INTO ( PARTITION
      fee_katy1, PARTITION fee_katy2);

假设fee_katy分区的取值为[90-110),那么新拆分的两个分区的取值为fee_katy1=[90-100),fee_katy2=[100-110) .

时间间隔分区

ALTER TABLE transactions
    SPLIT PARTITION FOR(TO_DATE('01-MAY-2007','dd-MON-yyyy'))
    AT (TO_DATE('15-MAY-2007','dd-MON-yyyy'));


您可能感兴趣的文档:

--结束END--

本文标题: Oracle 学习之 性能优化(十二) 分区表

本文链接: https://www.lsjlt.com/news/40026.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Oracle 学习之 性能优化(十二) 分区表
    一、分区概念   Oracle允许将表、索引、索引组织表细分成更小的片,每个片我们称之为分区。分区有其自己的名字和存储参数。  如下图:每行数据只能属于一个分区,分区键决定数据...
    99+
    2022-10-18
  • Oracle 学习之 性能优化(十四) 内存
     Oracle数据库包含了如下基本内存组件System global area (SGA)The SGA is a group of shared memory structures, known...
    99+
    2022-10-18
  • Oracle 学习之性能优化(二)游标
      游标是cursor的中文翻译,那么到底什么是cursor呢?Oracle Concept中是这样描述的:  When an application issues a SQL stat...
    99+
    2022-10-18
  • Oracle 学习之性能优化(十一)物化视图
      物化视图主要用于预先计算并保存表连接或聚集等耗时较多的操作的结果,这样,在执行查询时,就可以避免进行这些耗时的操作,而从快速的得到结果。在数据仓库中,还经常使用查询重写(query rewri...
    99+
    2022-10-18
  • Oracle 学习之 性能优化(十五) ASH、ADDM、AWR
    ASH(Active Session History)  ASH以V$SESSION为基础,每秒采样一次,记录活动会话等待的事件。不活动的会话不会采样,采样工作由新引入的后台进程MMNL来完成。A...
    99+
    2022-10-18
  • Oracle 学习之性能优化(八)优化器
       我们知道,在sql语句解析的过程中,有一个过程叫优化。Oracle中有一个叫优化器的组件,专门来处理sql的优化。在考虑查询条件和对象引用的许多相关因素后,优化器能确定出执行SQL语句最有效...
    99+
    2022-10-18
  • Oracle 学习之性能优化(九)使用hint
            基于代价的优化器是很聪明的,在绝大多数情况下它会选择正确的优化器,减轻了DBA的负担。但有时它也聪明反被聪明误,选择了很差的执行计划,使某个语句的执行...
    99+
    2022-10-18
  • Oracle 学习之性能优化(三)绑定变量
      根据Oracle 学习之性能优化(二)游标中的描述,我们知道如下两条语句是不共享的。select * from emp where&...
    99+
    2022-10-18
  • Oracle 学习之性能优化(六)访问路径
      访问路径是指Oracle找到用户需要的数据的方法,这些方法很少,包括:声名狼藉的全表扫描--人们不惜一切视图避免的(曲解的)访问路径。各种类型的索引扫描--这是人们感觉良好的访问路径(多数情况...
    99+
    2022-10-18
  • Oracle 学习之性能优化(一)SQL语句处理
      当向Oracle提交一个sql命令时,Oracle到底做了哪些事情?对这个问题有很好的理解,能帮助你更好的分析sql语句的优化。  执行一条sql语句从开始到结束,需要经历4个步骤:...
    99+
    2022-10-18
  • Oracle 学习之性能优化(四)收集统计信息
     emp表有如下数据。SQL> select ename,deptno from emp; ENAME   &n...
    99+
    2022-10-18
  • Oracle 学习之性能优化(七)join的实现方式
      本文讨论一下join技术背后的机制。我们知道常用的表连接有如下几种笛卡尔连接内连接左外连接右外连接全连接这些sql的写法,想必大家都很清楚了,那么这些连接的数据访问是如何实现的呢?nested...
    99+
    2022-10-18
  • SQLSERVER使用表分区优化性能
    目录1.简介2.表分区2.1分区范围2.2分区键2.3索引分区3.创建表分区3.1创建文件组3.2指定文件组存放路径3.3创建分区函数3.4创建分区方案3.5创建分区表3.6创建分区...
    99+
    2022-11-13
  • 优化iOS程序性能的二十五个方法分别是哪些
    这篇文章给大家介绍优化iOS程序性能的二十五个方法分别是哪些,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。1. 用ARC管理内存ARC(Automatic ReferenceCount...
    99+
    2022-10-19
  • MySQL性能优化及分区、分表的详细步骤
    本文主要给大家简单讲讲MySQL性能优化及分区、分表的详细步骤,相关专业术语大家可以上网查查或者找一些相关书籍补充一下,这里就不涉猎了,我们就直奔主题吧,希望MySQL性能优化及分区、分表的详细步骤这篇文章...
    99+
    2022-10-18
  • 索引优化系列十四--啥时分区索引性能反而低
    drop table part_tab purge;create table part_tab (id int,col2 int,col3 int)      &nb...
    99+
    2022-10-18
  • MySQL性能调优之分区表的知识点有哪些
    本篇内容主要讲解“MySQL性能调优之分区表的知识点有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“MySQL性能调优之分区表的知识点有哪些”吧!对于用户而...
    99+
    2022-10-19
  • Go语言中数组如何优化性能?学习笔记带你走进优化之路!
    数组是计算机科学中最基本的数据结构之一。在Go语言中,数组是一个固定长度、由相同类型元素组成的序列。在一些高性能的场景中,如图形处理、游戏开发、大规模数据处理等,数组的性能优化显得尤为重要。本篇文章将介绍Go语言中数组的性能优化方法,带你...
    99+
    2023-10-20
    数组 学习笔记 http
  • 分而治之:Oracle 18c及12.2分区新特性的N种优化实践
    本文根据杨廷琨2018年5月11日在【第九届中国数据库技术大会】上的演讲内容整理而成。   讲师介绍:   杨廷琨,高级咨询顾问, ITPUB Oracle 数据库管理版版主 ,人称...
    99+
    2022-10-18
  • Oracle提升查询性能之-简单范围分区表的创建
    分区表的优点: 1.提高查询性能:只需要搜索特定分区,而非整张表,提高了查询速度。 2.节约维护时间:单个分区的数据装载,索引重建,备份,维护远远小于整张表的维护时间。下面就让我们来创建一张分区表 第一步:...
    99+
    2022-10-18
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作