SQL查询优化——表分区

  • Post author:
  • Post category:其他



1.表分区:


在建表的时候将表建成分区表


2.好处:


a1.提高对数据检索或操作的效率

a2.不同的分区可以保存到不同的表空间(磁盘),提高数据的安全性

a3.可以将数据分到不同的分区

a4.每个分区的数据可以独立的备份和恢复


3.表分区的方法:


a1.范围分区

a2.散列分区

a3.列表分区

a4.复合分区


4. 维护分区


a1.增加新的分区

a2.删除分区

a3.截断分区

a4.合并分区

a5.拆分分区

a6.重命名表分区




范围分区表

-ordertable(orderid,money,orderdate,userid)



按订单时间来进行分区-范围分区表




-2019一季度的订单—分区Q1下

–2019二季度的订单—分区Q2下

–2019三季度的订单—分区Q3下

–2019四季度的订单—分区Q4下

–其它时间的订单—- 分区Q5下

语法:

create table 表名(

列的描述,

列的描述,



列的描述

)

partition by range(列名)

(

partition 分区名1 values less than(值1) tablespace 表空间1,

partition 分区名2 values less than(值2) tablespace 表空间2,



partition 分区名n values less than(值n) tablespace 表空间n,

partition 分区名m values less than(maxvalue)

)

 CREATE TABLE ordertable(
  orderid NUMBER PRIMARY KEY,--订单编号
  money NUMBER(12,2) NOT NULL,--订单金额
  orderdate DATE NOT NULL, --下单时是
  userid NUMBER(8,0) NOT NULL --用户编号
 )
 PARTITION BY RANGE(orderdate)
 (
  PARTITION Q1 VALUES LESS THAN('31-3月-2019') TABLESPACE studb,
  PARTITION Q2 VALUES LESS THAN(to_date('2019-6-30','yyyy-MM-dd')) TABLESPACE testDB,
  PARTITION Q3 VALUES LESS THAN(to_date('2019-9-30','yyyy-MM-dd')) TABLESPACE testDB,
  PARTITION Q4 VALUES LESS THAN(to_date('2019-12-31','yyyy-MM-dd')) TABLESPACE testDB,
  PARTITION Q5 VALUES LESS THAN(MAXVALUE) TABLESPACE testDB
 )
 INSERT INTO ordertable VALUES (1,10000,'10-2月-2019',1000);--进入Q1分区
 INSERT INTO ordertable VALUES (2,8000,'10-1月-2019',1001);--进入Q1分区
 INSERT INTO ordertable VALUES (3,9000,'20-2月-2019',1002);--进入Q1分区
 INSERT INTO ordertable VALUES (4,3000,'10-3月-2019',1003);--进入Q1分区
  INSERT INTO ordertable VALUES (5,10000,'10-4月-2019',1000);--进入Q2分区
 INSERT INTO ordertable VALUES (6,8000,'10-5月-2019',1001);--进入Q2分区
 INSERT INTO ordertable VALUES (7,9000,'20-6月-2019',1002);--进入Q2分区
 INSERT INTO ordertable VALUES (8,3000,'10-7月-2019',1003);--进入Q3分区
  INSERT INTO ordertable VALUES (9,10000,'10-8月-2019',1000);--进入Q3分区  
   INSERT INTO ordertable VALUES (10,8000,'10-9月-2019',1001);--进入Q3分区  
   INSERT INTO ordertable VALUES (11,9000,'20-10月-2019',1002);--进入Q4分区 
   INSERT INTO ordertable VALUES (12,3000,'10-11月-2019',1003);--进入Q4分区 
   INSERT INTO ordertable VALUES (13,3000,'10-11月-2018',1003);--进入Q1分区 
   INSERT INTO ordertable VALUES (14,3000,'10-3月-2020',1003);--进入Q5分区  
   SELECT * FROM ordertable   
   
 --查询Q1分区的数据   
     SELECT * FROM ordertable  PARTITION(Q5)  
     WHERE userid=1000    
    --修改`在这里插入代码片`第一季度,用户编号为1002这个订单的金额为19000
   UPDATE ordertable PARTITION(Q1) SET money=19000 WHERE userid=1002   
 --删除第一季度,用户编号为1002这个订单  
    DELETE FROM ordertable PARTITION(Q1) WHERE userid=1002




散列分区

根据客户名字,创建散列分区,分成4个分区

  CREATE TABLE customer(
  cusId NUMBER(10,0) PRIMARY KEY,--客户编号
  cusName VARCHAR2(30) NOT NULL,--客户名
  age NUMBER(3,0) NOT  NULL, --年龄 
  phone VARCHAR2(20) NOT NULL --电话
  )
  PARTITION BY HASH(cusName)
  PARTITIONS 4
  INSERT INTO customer2 VALUES (1,'钟俊1',20,'133213213');
  INSERT INTO customer2 VALUES (2,'中唐',20,'133213213');
  INSERT INTO customer2 VALUES (3,'多唐',20,'133213213');
  INSERT INTO customer2 VALUES (4,'低唐',20,'133213213');
  INSERT INTO customer2 VALUES (5,'不加糖',20,'133213213');
  INSERT INTO customer2 VALUES (6,'白沙糖',20,'133213213');
  INSERT INTO customer2 VALUES (7,'红糖',20,'133213213');
  INSERT INTO customer2 VALUES (8,'冰糖',20,'133213213');
  SELECT * FROM customer PARTITION (SYS_P45) ORDER BY cusid ASC  --3,5,6
  SELECT * FROM customer PARTITION (SYS_P46) ORDER BY cusid ASC --4
  SELECT * FROM customer PARTITION (SYS_P47) ORDER BY cusid ASC --1,7,8
  SELECT * FROM customer PARTITION (SYS_P48) ORDER BY cusid ASC --2
  CREATE TABLE customer2(
  cusId NUMBER(10,0) PRIMARY KEY,--客户编号
  cusName VARCHAR2(30) NOT NULL,--客户名
  age NUMBER(3,0) NOT  NULL, --年龄 
  phone VARCHAR2(20) NOT NULL --电话
  )
  PARTITION BY HASH(cusName)
(
 PARTITION p1 TABLESPACE studb,
 PARTITION p2 TABLESPACE zhilingdb,
 PARTITION p3 ,
 PARTITION p4
)
`SELECT * FROM customer2 PARTITION(p1)`**

———————————————————**

–**



列表分区

** ,根据学生的地址address将数据保存到不同的分区下

CREATE TABLE stu_temp2(
    stuid NUMBER(10,0) PRIMARY KEY,
    stuname VARCHAR2(30) NOT NULL,
    address VARCHAR2(20) NOT NULL,
    phone VARCHAR2(30) NOT NULL
  
  )
  PARTITION BY LIST(address)
  (
  PARTITION guangdong VALUES ('广东省') TABLESPACE zhilingdb,
  PARTITION hubei VALUES ('湖北省') TABLESPACE zhilingdb,
  PARTITION hunan VALUES ('湖南省') TABLESPACE studb,
  PARTITION guangxi VALUES ('广西省') TABLESPACE zhilingdb,
  PARTITION hebei VALUES ('河南省') TABLESPACE zhilingdb ,
  PARTITION qita VALUES (DEFAULT)
  )
 INSERT INTO stu_temp2 VALUES (1,'小张','广东省',110);
 INSERT INTO stu_temp2 VALUES (2,'小李','湖北省',110);
 INSERT INTO stu_temp2 VALUES (3,'小何','湖南省',110);
 INSERT INTO stu_temp2 VALUES (4,'小钟','湖北省',110);
 INSERT INTO stu_temp2 VALUES (5,'小徐','湖南省',110);
 INSERT INTO stu_temp2 VALUES (6,'小黄','河南省',110);
 INSERT INTO stu_temp2 VALUES (7,'小虎','河南省',110);
 INSERT INTO stu_temp2 VALUES (8,'小强','北京',110);
 SELECT * FROM stu_temp2 PARTITION(hunan)



复合分区

:外层是范围分区,子分区是列表分区

create table customer3(
   customerid number primary key,
   customername varchar2(30) not null,
   phone varchar2(30) not null,
   address varchar2(30) not null
 )
 partition by range(customerid)
 subpartition by list (address)
 (
 partition customer3_p1 values less than (10000)
  (subpartition p1_gd values ('广东'),subpartition p1_gx values ('广西'),subpartition p1_qt values (DEFAULT)), 
 partition customer3_p2 values less than (maxvalue) (subpartition p2_gd values ('广东'),subpartition p2_gx values ('广西'),subpartition p2_qt values (DEFAULT))
 
 )
 INSERT INTO customer3 VALUES (1,'aa','110','广东');
 INSERT INTO customer3 VALUES (2,'bb','110','广西');
 INSERT INTO customer3 VALUES (3,'cc','110','湖北');
 INSERT INTO customer3 VALUES (4,'dd','110','广东');
 INSERT INTO customer3 VALUES (5,'dd','110','湖南');
  INSERT INTO customer3 VALUES (20000,'aa','110','广东');
 INSERT INTO customer3 VALUES (20001,'bb','110','广西');
 INSERT INTO customer3 VALUES (20002,'cc','110','湖北');
 INSERT INTO customer3 VALUES (20003,'dd','110','广东');
 INSERT INTO customer3 VALUES (20004,'dd','110','湖南');
 --查询客户id<10000的下的广东的客户(直接指定子分区名字查询)
 SELECT * FROM customer3  subpartition(p2_gx) 
 ROLLBACK
 COMMIT;
 SELECT * FROM ordertable PARTITION(Q2_2020) 
 ------------------------------------------------

–删除Q5分区:同步删除该分区的数据

ALTER TABLE ordertable DROP PARTITION def_part

–增加分区:为2020年第一季度增加新的分区

ALTER TABLE ordertable ADD PARTITION Q1_2020 VALUES LESS THAN('31-3月-2020')
ALTER TABLE ordertable ADD PARTITION Q2_2020 VALUES LESS THAN('30-6月-2020')
INSERT INTO ordertable VALUES (20,5000,'1-4月-2020',1000)

–删除分区:删除表分区时,表分区及表分区中的数据也随之删除

ALTER TABLE customer3 DROP PARTITION customer3_p1

–截断分区:截断表分区时,删除表分区中的数据,表分区还在,也不影响其它表分区

ALTER TABLE ordertable TRUNCATE PARTITION Q2_2020

–截断分区:截断子表分区时,删除表分区中的数据,表分区还在,也不影响其它表分区

ALTER TABLE ordertable TRUNCATE SUBPARTITION  PARTITION customer3_p1_sub

–合并表分区-将范围分区或复合分区的两个相邻分区连接起来

ALTER TABLE ordertable MERGE PARTITIONS q1_2019,q2_2019 INTO PARTITION q7_2019

–重命名表分区

ALTER TABLE SALES RENAME PARTITION P21 TO P2;

–拆分分区 – 将一个大分区中的记录拆分到两个分区中

ALTER TABLE SALES SPLIT PARTITION P2 AT (5000)
INTO (PARTITION P21, PARTITION P22);

–跨分区查询

select sum(*) from (
     select count(*) cn from t_table_SS PARTITION (P200709_1)--10
union all
     select count(*) cn from t_table_SS PARTITION (P200709_2)--20
);



版权声明:本文为MrGongx原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。