Oracle 表分区笔记
当表中的数据量不断增大,查询数据的速度就会变慢,应用程序的性能就会下降,这时就应该考虑对表进行分区。表进行分区后,逻辑上表仍然是一张完整的表,只是将表中的数据在物理上存放到多个表空间(物理文件上),这样查询数据时,不至于每次都扫描整张表。
优点
- 数据查询:数据被存储到多个文件上,减少了I/O负载,查询速度提高。
- 数据修剪:保存历史数据非常的理想。
- 备份:将大表的数据分成多个文件,方便备份和恢复。
- 并行性:可以同时向表中进行DML操作,并行性性能提高,均衡I/O:可以把不同的分区映射到磁盘以平衡I/O,改善整个系统性能。
- 增强可用性:如果表的某个分区出现故障,表在其他分区的数据仍然可用;
- 维护方便:如果表的某个分区出现故障,需要修复数据,只修复该分区即可;
- 改善查询性能:对分区对象的查询可以仅搜索自己关心的分区,提高检索速度。
- 需要注意的是包含LONG、LONGRAW数据类型的表不能分区,如果表格大于2G需要考虑分区。
种类
(1)范围分区(range)——我们这篇博文的内容;
(2)哈希分区(hash);
(3)列表分区(list);
(4)范围-哈希复合分区(range-hash);
(5)范围-列表复合分区(range-list)。
Range 分区
Range分区是应用范围比较广的表分区方式,它是以列的值的范围来做为分区的划分条件,将记录存放到列值所在的range分区中。
如按照时间划分,2010年1月的数据放到a分区,2月的数据放到b分区,在创建的时候,需要指定基于的列,以及分区的范围值。
在按时间分区时, 如果某些记录暂无法预测范围,可以创建 maxvalue 分区,所有不在指定范围内的记录都会被存储到 maxvalue 所在分区中。
函数
numtodsinterval
numtodsinterval(<x>,<c>)
,其中x是一个数字,c是一个字符串,
表明x的单位,这个函数把x转为interval day to second数据类型
常用的单位有 (day
,hour
,minute
,second
)
select sysdate,sysdate+numtodsinterval(3,'hour') as res from dual;
分区索引
对于分区索引,需要区分创建的是全局索引(global index)还是本地索引(local index)。
全局索引(global index)
即可以分区,也可以不分区。即可以建range 分区,也可以建hash 分区, 即可建于分区表,又可创建于非分区表上,就是说,全局索引是完全独立的,因此它也需要我们更多的维护操作。
特点:
- 全局索引的分区键和分区数和表的分区键和分区数可能都不相同,表和全局索引的分区机制不一样。
- 全局索引可以分区,也可以是不分区索引,全局索引必须是前缀索引,即全局索引的索引列必须是以索引 分区键作为其前几列。
- 全局分区索引的索引条目可能指向若干个分区,因此,对于全局分区索引,即使只动,截断一个分区中 的数据,都需要rebulid若干个分区甚至是整个索引。
- 全局索引多应用于oltp系统中。
- 全局分区索引只按范围或者散列hash分区,hash分区是10g以后才支持。
- oracle9i以后对分区表做move或者truncate的时可以用update global indexes语句来同步 更新全局分区索引,用消耗一定资源来换取高度的可用性。
- 表用a列作分区,索引用b做局部分区索引,若where条件中用b来查询,那么oracle会扫描所有的 表和索引的分区,成本会比分区更高,此时可以考虑用b做全局分区索引 。
本地索引(local index)
其分区形式与表的分区完全相同,依赖列相同,存储属性也相同。 对于本地索引,其索引分区的维护自动进行,就是说你add/drop/split/truncate 表的分区时, 本地索引会自动维护其索引分区。
特点:
- 局部索引一定是分区索引,分区键等同于表的分区键,分区数等同于表的分区说,一句话,局部索引的 分区机制和表的分区机制一样。
- 如果局部索引的索引列以分区键开头,则称为前缀局部索引。
- 如果局部索引的列不是以分区键开头,或者不包含分区键列,则称为非前缀索引。
- 前缀和非前缀索引都可以支持索引分区消除,前提是查询的条件中包含索引分区键。
- 局部索引只支持分区内的唯一性,无法支持表上的唯一性,因此如果要用局部索引去给表做唯一性约束, 则约束中必须要包括分区键列。
- 局部分区索引是对单个分区的,每个分区索引只指向一个表分区,全局索引则不然,一个分区索引能指向n个表分区,同时,一个表分区,也可能指向n个索引分区,对分区表中的某个分区做truncate 或者move,shrink等,可能会影响到n个全局索引分区,正因为这点,局部分区索引具有更高的可用性。
- 位图索引只能为局部分区索引。
- 局部索引多应用于数据仓库环境中。
创建本地索引示例
create index zt_wgxx_re_date_time on zt_wgxx(RECEIVE_DATE_TIME) local
常见错误
ORA-14060
创建好分区表后,分区字段的属性不能修改的,否则会报错ORA-14060: 不能更改表分区列的数据类型或长度
ORA-14751
Oracle 11g中推出的Interval特性,是针对Range类型分区的一种功能拓展,Interval支持的Range分区键类型只有number
、date
、timestamp
三种类型。其他类型字段做alter table tablename set INTERVAL()时会报错ORA-14751: 间隔分区表的分区列的数据类型无效
ORA-14300
当START_TIME的值为NULL时,然后向分区对象表插入数据,数据库不知道将该条记录插入到哪个分区,导致报错ORA-14300: 分区关键字映射到超出允许的最大分区数的分区
ORA-14752
ORA-14752: 间隔表达式不是正确类型的常数,应该查看是否写错了,日和周的是 NUMTODSINTERVAL,年的和月的 是 NUMTOYMINTERVAL
ORA-14767
ORA-14767: 无法使用现有上限指定此间隔,你时间写的不对,时间不可以超过指定时间,避免这种错误其实很简单,最简单的是利用28日作为分区上限
分区表创建示例
先说下,里面有两个地方需要注意,一个是分区字段名,这里用的是:WORKDATE
,需要有个分区字段;
另外一个是划分分区时间的 less than(XXXX)
,这个时间是比较特殊,超过这个时间会自动创建额外的分区,但暂时这么理解吧,我一般管它叫默认时间,也可以创建多个,但是我都只创建一个,后续会自增。
对于是月的,年的建议设置时间为每个月的01月1日。
创建日分区表
create table TTT(WORKDATE date)
PARTITION BY RANGE (WORKDATE) INTERVAL (NUMTODSINTERVAL(1,'day'))
( partition P_1995 values less than (TO_DATE('1995-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS')));
创建月分区表
create table TTT(WORKDATE date)
PARTITION BY RANGE (WORKDATE) INTERVAL (NUMTOYMINTERVAL(1,'month'))
( partition P_1995 values less than (TO_DATE('1995-12-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS')));
创建年分区表
create table TTT(WORKDATE date)
PARTITION BY RANGE (WORKDATE) INTERVAL (NUMTOYMINTERVAL(1,'year'))
( partition P_1995 values less than (TO_DATE('1995-12-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS')));
类型示例
DATE类型
DATE类型:建立的分区表说明2003-1-1之前的数据放入P01分区中,之后的数据每天一个分区
CREATE TABLE tablename (hid number,hdate date)
PARTITION BY RANGE(hdate) INTERVAL (NUMTODSINTERVAL(1, 'DAY'))
( PARTITION p01 VALUES LESS THAN (to_date('2003-1-1','yyyy-mm-dd')));
number类型
number类型:建立的分区表说明100之前的数据放入P01分区中,之后的数据每100放入一个新一个分区,比如102放入一个分区p02,203放入一个分区p03 如果只有100以内的数据,还没有大于100的数据,直接插入1111则一样自动建立一个分区,USER_TAB_PARTITIONS.HIGHVALUE显示为1200,再插入103一样会自动建立一个分区,USER_TAB_PARTITIONS.HIGHVALUE显示为200
CREATE TABLE tablename (hid number,hdate date)
PARTITION BY RANGE(hid) INTERVAL (100)
( PARTITION p01 VALUES LESS THAN (100));
当如如果建表的时候没有指定 INTERVAL
--修改每100为单位分区则可以手工修改如下
alter table tablename set INTERVAL (100);
--修改每天分区则可以手工修改如下
alter table tablename set INTERVAL (NUMTODSINTERVAL(1, 'DAY'));
--修改为每周分区则如下
alter table tablename set INTERVAL(numtodsinterval(7,'day'));
--修改为每月分区则如下
alter table tablename set INTERVAL(numtoyminterval(1,'MONTH'));
--修改为每年分区则如下
alter table tablename set INTERVAL(numtoyminterval(1,'YERA'));
--numtodsinterval(<x>,<c>) ,x是一个数字,c是一个字符串,c只能是'DAY'、'HOUR'、'MINUTE'、'SECOND'
--numtoyminterval(<x>,<c>) ,x是一个数字,c是一个字符串,c只能是'YEAR'、'MONTH'
实操
create table ZT_WGXX
(
ID VARCHAR2(50) not null
constraint PK_ZT_WGXX
primary key,
PROJECT_ID VARCHAR2(50),
CAR_ID VARCHAR2(50),
TRAFFICCOMPANY_ID VARCHAR2(50),
TYPE VARCHAR2(50),
WGNR VARCHAR2(2000),
CREATE_DATE DATE not null,
CREATE_BY VARCHAR2(50) not null,
UPDATE_DATE DATE,
UPDATE_BY VARCHAR2(50),
REMARKS VARCHAR2(250),
DEL_FLAG NUMBER(4),
MAP_X VARCHAR2(50),
MAP_Y VARCHAR2(50),
SYSTEM_FLAG VARCHAR2(50),
ARTIFICIAL_FLAG VARCHAR2(50),
RECEIVE_DATE_TIME DATE,
RECEIVE_DATE VARCHAR2(250),
RECEIVE_DATE_END VARCHAR2(250),
XWFSDD_NAME VARCHAR2(500)
) PARTITION BY RANGE (RECEIVE_DATE_TIME) INTERVAL (NUMTODSINTERVAL(1, 'day'))
(PARTITION ZT_WGXX_pt01 VALUES LESS THAN (to_date('2000-1-1', 'yyyy-mm-dd')));
说明:
INTERVAL 分区,按天分区,需要用到函数NUMTODSINTERVAL
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 2020 年,苹果的 AI 还有创新吗?
- 毕设有着落了!一套开源的,基于SpringBoot的车牌识别系统
- 详解hive的join优化
- 区块链时代的世界宪章:代码即法律
- SQL 计算公司的期初资产
- nested exception is java.lang.IllegalStateException: refreshAfterWrite requires
- 除了会排序,你对ORDER BY的用法可能一无所知!
- 修改xposed特征并刷机
- Python 爬虫进阶必备 | 关于某租房网站数据加密的分析
- CMAKE学习记录(二)
- maven 中的版本依赖冲突问题
- Manual for Ubuntu Installation
- 修改自定义站点监控页面的样式
- 快速建站“新玩具”—glitch.me
- 踩坑记 | Flutter升级影响了NestedScrollView?