Oracle-性能优化篇-分区表

🍓Oracle分区表

  • 📌优点:
    1. 改善查询性能:对分区对象的查询可以仅搜索自己关心的分区,提高检索速度(个人评价只针对条件中带分区字段的查询性能)。
    2. 增强可用性:如果表的某个分区出现故障,表在其他分区的数据仍然可用(鸡蛋不放一个篮子里的概念)。
    3. 维护方便:如果表的某个分区出现故障,需要修复数据,只修复该分区即可(各数据文件之间相互独立,互不影响)。
    4. 均衡I/O:可以把不同的分区映射到不同磁盘以平衡I/O,改善整个系统性能(这个针对整体的查询性能,但是分区必须放在不同的表空间,每个表空间尽量分布在不同的磁盘上,这样可以充分利用各个磁盘的I/O来提高效率)。
  • 📌缺点:
    分区表相关:已经存在的表没有方法可以直接转化为分区表。不过 Oracle 提供了在线重定义表的功能。

🍓分区表

🍒范围分区(Range)

适合于有明确的时间线或者表里有能表示范围的字段的大批量数据。

create table T_USERS_INFO(
--userID设置的主键,这里就不展示主键设置语句了
userID number,
name varchar2(100),
age number,
birthday date
)
--范围分区
partition by range(birthday) (
--不想指定分区的表空间,可以去掉tablespace xxx
partition p_2020 values less than(to_date('2021-01-01','yyyy-MM-dd')) tablespace p_userinfo_2020,
partition p_2021 values less than(to_date('2022-01-01','yyyy-MM-dd')) tablespace p_userinfo_2021,
partition p_2022 values less than(to_date('2023-01-01','yyyy-MM-dd')) tablespace p_userinfo_2022,
partition p_max values less than(maxvalue) tablespace p_userinfo_max  --兜底,如果不加这个,超出范围的数据插入则将报错。包括空值都是放到这个兜底里面的。
)

--查询表的分区信息
select table_name,partition_name,tablespace_name from dba_tab_partitions where table_name = 'T_USERS_INFO';

--查询指定分区的数据
select * from T_USERS_INFO partition(p_2022)  
🍒List分区

适合于表里存在固定值的字段,如性别、年级等

create table T_USERS_INFO2(
name varchar2(100),
age number,
sex varchar2(10)
)
--指明它是list分区
partition by list(sex)(
--这里设的是固定值,不是范围
partition p_man values ('男') ,
partition p_woman values('女'),
partition p_max values(default)  --兜底,如果不加这个,超出范围的数据插入则将报错。 包括空值都是放到这个兜底里面的。
)
🍒Hash散列分区

适合于表里没有任何规律的字段。

create table T_USERS_INFO3
(
  name VARCHAR2(100),
  age  NUMBER,
  sex  VARCHAR2(10)
)
--指明它是hash分区
partition by hash (AGE)(
partition P1 tablespace p_user_info_1,
partition P2 tablespace p_user_info_2  --hash散列分区不需要兜底分区
);

🍓引用分区

引用分区是给子表分区,适合与已存在的分区表有关联关系的表。

--创建引用分区,引用分区父表T_USERS_INFO
create table T_USER_PERSON(
userInfoID number not null,
pname varchar2(100),
relation varchar2(100),
--注意:子表的外键必须对应分区父表的主键,但是主键不是必须的分区字段
constraint userid_re foreign key(userInfoID) references T_USERS_INFO(userID)
)
partition by reference(userid_re);

🍓组合分区

根据多个字段进行分区(用于单个字段分区后每个分区的数据依然很多,使用组合分区可以对分区进行再分区)

create table T_USERS_INFO4(
name varchar2(100),
age number,
sex varchar2(10) 
)
--首先按照age范围分区
partition by range(age)
--在age范围分区中再按照sex进行list分区
subpartition by list(sex)(
partition p_18 values less than(18) tablespace p_userinfo4_18(
subpartition p_18_man values ('男') ,
subpartition p_18_woman values ('女'),
subpartition p_18_default values(default) 
),
partition p_30 values less than(30) tablespace p_userinfo4_30(
subpartition p_30_man values ('男') ,
subpartition p_30_woman values ('女'),
subpartition p_30_default values(default) 
),
partition p_50 values less than(50) tablespace p_userinfo4_50(
subpartition p_50_man values ('男') ,
subpartition p_50_woman values ('女'),
subpartition p_50_default values(default) 
),
partition p_70 values less than(70) tablespace p_userinfo4_70(
subpartition p_70_man values ('男') ,
subpartition p_70_woman values ('女'),
subpartition p_70_default values(default) 
),
partition p_max values less than(maxvalue) tablespace p_userinfo4_max(
subpartition p_max_man values ('男') ,
subpartition p_max_woman values ('女'),
subpartition p_max_default values(default) 
)
)

#查询子分区的数据
select * from T_USERS_INFO4 subpartition (p_18_man)

#查询子分区的信息
select table_owner,table_name,partition_name,subpartition_name,tablespace_name from dba_tab_subpartitions where table_name = 'T_USERS_INFO4';

🍓分区索引

分区表一般创建本地索引,本地索引在分区表中就是分区索引,各个分区之间的索引相互独立,可以避免因为删除某个分区而导致索引失效的问题。

--创建本地索引
create index user_info_age on T_USERS_INFO(age) local;

--查看索引状态
--STATUS:索引状态(VALID:有效索引,N/A:有效分区索引,UNUSABLE:无效索引)
--PARTITIONED:是否分区索引
select STATUS, PARTITIONED from all_indexes where table_name = 'T_USERS_INFO'

注意: 唯一索引、主键索引,要创建本地索引时,需要带上分区字段进行创建。

🍓分区的新增与删除

🍒手动新增分区

以时间为范围分区的,随着时间的推移我们需要不断给数据库添加新的分区,或者清理数据库中久远的存量分区。

--新增分区(新增的分区会将P_MAX中符合条件的数据自动归集到该新分区中去)
alter table 表名 split partition P_MAX at(to_date(分区界限的时间,'YYYY/mm/dd')) into (partition 分区名,partition P_MAX);
	--demo
	alter table T_USERS_INFO split partition P_MAX at(to_date('2024-01-01','yyyy-MM-dd')) into (partition p_2023,partition p_MAX);

--删除分区数据
alter table 表名 truncate partition 分区名称;

--删除分区
alter table 表名 drop partition 分区名称;

--注意:truncate和drop都会导致索引失效,建议把分区表的索引建成本地索引(分区索引),防止这种情况发生!
🍒oracle自动创建分区

在创建表时,带上interval(NUMTOYMINTERVAL(1, 'YEAR/MONTH/DAY'))便可以自动创建分区了,加上这个的分区表只需要在创表时创建一个初始分区即可,禁止创建兜底分区与该语句一起使用。

create table T_USERS_INFO(
--userID设置的主键,这里就不展示主键设置语句了
userID number,
name varchar2(100),
age number,
birthday date
)
--范围分区
partition by range(birthday) interval(NUMTOYMINTERVAL(1, 'YEAR'))(
--不想指定分区的表空间,可以去掉tablespace xxx
partition p_2022 values less than(to_date('2023-01-01','yyyy-MM-dd')) tablespace p_userinfo_2022
)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值