什么是Oracle的分区表.docx
- 文档编号:4889739
- 上传时间:2023-05-07
- 格式:DOCX
- 页数:15
- 大小:20.61KB
什么是Oracle的分区表.docx
《什么是Oracle的分区表.docx》由会员分享,可在线阅读,更多相关《什么是Oracle的分区表.docx(15页珍藏版)》请在冰点文库上搜索。
什么是Oracle的分区表
什么是Oracle的分区表?
假设我们现在正在酝酿经营一家图书馆,最初,我们只有十本书提供给大家来阅读和购买。
对于十本书而言,我们可能只需要一个书架格子将其作为保存这十本书的容器就足够了,因为任何一个人都可以很轻松的扫一眼就可以将这十本书的书名大概记住,并且挑选出合适自己的书籍来看。
但是随着我们书籍越来越多,我们需要更大的容器来保存我们的科教类、IT类、历史类、人文类等等书籍,大家都知道的一个生活常识就是,我们肯定不能够将所有类型的书籍都扔到一个书架容器上摆着,最科学的,就是分区,将不同的书籍放到不同的地方去,这样,假如我们在西安五路口的新华书店,那么就只需要跑到四楼的IT分区,去找相关的IT书籍。
在生活中是这个样子,在数据库中呢?
现在的数据库业务数据和日志数据,以几何级数的速度在增长着。
以我之前从事社保行业为例,社保的日志动辄几十G,其实,其中几乎涵盖了从系统试运行到运行一两年之后的数据,这样一个巨大的表,让数据的逻辑备份、查询、甚至基于日志表的回退都产生了巨大的效率问题。
如何能够快速有效的删除三个月之前的日志信息,如何能够快速的检索当前月份的信息,如何充分利用多块磁盘空间(裸设备)的物理环境,增加并行度平衡I/O从而改善性能增强数据库的可用性?
Oracle在8.0版本之后提出的表的分区功能就是一个非常关键的实用技术。
早在8.0.5版本中,Oracle就将范围分区技术引入,现在分区功能已经越来越强大,包括支持扩展分区功能、Interval分区、外键分区、模拟列分区、以及分区建议器等。
那么,分区到底有什么好处呢?
我们为什么要使用分区呢?
在什么环境下使用分区比较合适呢?
在金牌管理群中,有一个哥们请教一个多用户下一张10W频繁表的增加、删除、修改表的问题,很多朋友给出了修改其成为分区表的建议。
其实,这张表能否将其设置为分区表,是需要看具体的业务使用环境的,多用户下频繁的增删改查,我认为应当使用全局临时表而非使用分区表,这个并不是分区表的典型应用环境,相反,应当是全局临时表的应用环境,并且在一本参考书中,找到了一位大牛的建议作为佐证:
“分区表应用在大表更合适,至少要大于100万条的记录才可以考虑使用分区表”,例如社保系统中,使用分区表解决日志问题冗余问题就是一个最佳使用场景。
这个结论是非常容易理解的,就类似于我们最前面引入的一个例子,我们开书店,只有十本书,假设未来也只会有那么几本,那么我们为什么要费尽心思的分成不同的区域呢?
那岂不是画蛇添足了么?
既不经济也不和谐,只有当我们采购的书籍的量非常大的时候,我们才会去考虑使用分区技术来解决查找效率问题。
假设现在用户希望找到一本《数据结构》的教科书,我们在100W本书籍里面大海捞针的去找快呢?
还是在10W本IT类书籍中去查找快呢?
答案是显而易见的。
当我们只有10本书呢?
我们还会建立分区吗?
我们直接肉眼全部扫描一下,直接得到这本书就好了。
因此我们需要在特定的环境下选择特定的技术解决方案,目的是追求更高的效能,更高的性能带来的必然是用户更高的满意度,更高的满意度带来的必然是更好的经济效益,更好的经济效益带来的必然是图书管理员们更美好的生活。
那么就让我们看一下Oracle提供的分区功能到底有什么样子的好处呢?
1)由于Oracle数据库可以将分区指定为不同的表空间,而不同的表空间是可以指向不同的磁盘设备的,在很多时候,磁盘设备的I/O速度是系统进行数据操作的瓶颈,而分区并行,则起到了优化物理硬件资源,从而缩短了执行的时间的作用。
2)分区,就类似于我们将图书分类放到了不同的区间中,这个时候,我们就可以只针对其中的某一类图书进行操作,比如进行该类书籍的查询、上架、下架、甚至将该类图书付之一炬,这带来了两个特别大的优势,第一,我们无视其他分区的数据;第二,我们可以很方便的对本区的数据进行删除操作。
3)提高了特定的查询速度,比如我们现在只需要查找IT类图书的数量,因为我们能够在第一意识中,排除其他非IT类书籍,必然会提高查询的性能。
4)节约维护的成本,传统的维护操作,例如重建索引等,因为有锁机制的存在,是会影响到其他人的读取和更新删除操作的,但是由于有了分区,我们在维护IT类书籍的时候,就不会对其他分类的数据造成影响,这个时候,可以降低因为维护数据而对其他系统数据产生的各种影响。
5)从安全的角度上而言,我们将不同的分区放在不同的表空间当中,就类似于我们没有将所有的鸡蛋放到一个篮子里面,必然会带来安全方面的提升。
Oracle提供了下面几种比较常见的分区方式:
1)范围分区(partitionbyrange)
我们可以想象范围分区的前提,假如我们现在有100W本书,如果分成10个分区,能够比较平均的将每一类维持在10W本左右,是最理想不过了,这样看起来即工整又漂亮。
因此,我们在建立范围分区的时候,如何选择范围分区的依据从而能够让数据均匀分布,是一个需要重点关注的问题。
在很多情况下,例如上述提到的社保系统中的日志表,使用日期进行分类就是一个比较好的分区方案,因为每个月产生的数据量都是大致相同的。
下面,我们通过脚本来创建一个基于月份的范围分区表(假设插入的数据全部都是2013年的数据):
DROPTABLEPART_LOG_CHENZWPURGE;
CREATETABLEPART_LOG_CHENZW(
LOG_IDNUMBER(20)PRIMARYKEY,
LOG_DATEDATE,
LOG_DESCVARCHAR2(20)
)
PARTITIONBYRANGE(LOG_DATE)
(
PARTITIONPART_LOG_01VALUESLESSTHAN(TO_DATE('2013-01-01','YYYY-MM-DD'))TABLESPACEDATA,
PARTITIONPART_LOG_02VALUESLESSTHAN(TO_DATE('2013-03-01','YYYY-MM-DD'))TABLESPACEDATA,
PARTITIONPART_LOG_03VALUESLESSTHAN(TO_DATE('2013-05-01','YYYY-MM-DD'))TABLESPACEDATA,
PARTITIONPART_LOG_04VALUESLESSTHAN(TO_DATE('2013-07-01','YYYY-MM-DD'))TABLESPACEDATA,
PARTITIONPART_LOG_05VALUESLESSTHAN(TO_DATE('2013-09-01','YYYY-MM-DD'))TABLESPACEDATA,
PARTITIONPART_LOG_06VALUESLESSTHAN(TO_DATE('2013-10-01','YYYY-MM-DD'))TABLESPACEDATA,
PARTITIONPART_LOG_07VALUESLESSTHAN(MAXVALUE)TABLESPACEDATA
);
上面的例子就是一个使用范围分区的典型例子,在创建表的时候使用PARTITIONBYRANGE关键字来指出进行分区的策略,其中PARTITIONBYLOG(LOG_DATE)指的是使用LOG_DATE来作为分区的字段,里面根据取值的大小,命名了7个分区来存放数据,每个分区还可以指定不同的表空间,第七个分区使用MAXVALUE来避免有数值没有被上面的范围圈定,这个就类似于SWITCH语法中的DEFAULT,不同的,这个并不是fallthrough的。
下面,我们来生成10万条数据来插入到表中,查看一下表中发生了什么样子的变化?
INSERTINTOPART_LOG_CHENZW
(LOG_ID,LOG_DATE,LOG_DESC)
SELECTLEVEL,
TO_DATE('2013-01-01','YYYY-MM-DD')+
NUMTODSINTERVAL(CEIL(DBMS_RANDOM.VALUE(0,365)),'DAY'),
LEVEL||'DESC'
FROMDUAL
CONNECTBYLEVEL<=100000;
首先,我们可以查询一下落在7、8月份的日志记录,就如同我们去新华书店只是去查找IT类的书籍一样,我们知道我们应当去那里寻找名字为PART_LOG_05分区的数据:
SELECTCOUNT
(1)FROMPART_LOG_CHENZWPARTITION(PART_LOG_05);
下面是在我本机的显示结果:
06:
50:
40ChenZw>SELECTCOUNT
(1)FROMPART_LOG_CHENZWPARTITION(PART_LOG_05);
COUNT
(1)
----------
16981
通过上面的结果可以很明显的看出,有16981条数据落在了7、8月份的分区中。
我们通过指定分区,将全部的注意力只放到此1.6W条左右的数据而不是全部的10W条数据上,可以很明显带来效能的提升。
有一个问题随之而来,我们应当如何知道,图书馆里面都有什么样子的分区呢?
我们如何才能知道正确的分区呢?
在新华书店中,往往在上电梯的时候,都会有一个指示牌,告诉你,IT类书籍在4楼,人文社科类图书在1楼....其实,Oracle数据库也提供了这个指引牌,那就是下面两个数据字典:
DBA_PART_TABLES和DBA_TAB_PARTITIONS,下面我们就翻一下两个“指示牌”中的内容:
SQL>
SELECTT.OWNERAS"所有者",
T.TABLE_NAMEAS"表名",
T.PARTITIONING_TYPEAS"分区类型",
T.SUBPARTITIONING_TYPEAS"子分区类型",
T.PARTITION_COUNTAS"子分区数量",
T.PARTITIONING_KEY_COUNTAS"分区键中列的数量",
T.SUBPARTITIONING_KEY_COUNTAS"子分区键中列的数量",
T.STATUSAS"分区表状态",
T.DEF_TABLESPACE_NAMEAS"默认表空间"
FROMDBA_PART_TABLEST
WHERET.TABLE_NAMEIN('PART_LOG_CHENZW');
所有者表名分区类型子分区类型子分区数量分区键中列的数量子分区键中列的数量分区表状态默认表空间
--------------------------------------------------------------------------------------------------------------------------
CHENZWPART_LOG_CHENZWRANGENONE710VALIDDATA
通过上面我们可以看到,表PART_LOG_CHENZW现在有7个分区,但是,我们并不能知道这7个分区都是存放什么样子的数据的?
我们到什么地方去找到我们希望的7、8月的数据呢?
SQL>
SELECTT.TABLE_OWNERAS"所有者",
T.TABLE_NAMEAS"表名",
T.COMPOSITEAS"是否组合分区",
T.PARTITION_NAMEAS"分区名",
T.SUBPARTITION_COUNTAS"子分区数",
T.HIGH_VALUEAS"分区上限",
T.HIGH_VALUE_LENGTHAS"分区上限长度",
T.PARTITION_POSITIONAS"分区在表中位置",
T.TABLESPACE_NAMEAS"所在表空间"
FROMDBA_TAB_PARTITIONST
WHERET.TABLE_NAMEIN('PART_LOG_CHENZW')
/
所有者表名是否组合分区分区名子分区数分区上限分区上限长度分区在表中位置所在表空间
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CHENZWPART_LOG_CHENZWNOPART_LOG_010TO_DATE('2013-01-0100:
00:
00','SYYYY-MM-DDHH24:
MI:
SS','NLS_CALENDAR=GREGORIA831DATA
CHENZWPART_LOG_CHENZWNOPART_LOG_020TO_DATE('2013-03-0100:
00:
00','SYYYY-MM-DDHH24:
MI:
SS','NLS_CALENDAR=GREGORIA832DATA
CHENZWPART_LOG_CHENZWNOPART_LOG_030TO_DATE('2013-05-0100:
00:
00','SYYYY-MM-DDHH24:
MI:
SS','NLS_CALENDAR=GREGORIA833DATA
CHENZWPART_LOG_CHENZWNOPART_LOG_040TO_DATE('2013-07-0100:
00:
00','SYYYY-MM-DDHH24:
MI:
SS','NLS_CALENDAR=GREGORIA834DATA
CHENZWPART_LOG_CHENZWNOPART_LOG_050TO_DATE('2013-09-0100:
00:
00','SYYYY-MM-DDHH24:
MI:
SS','NLS_CALENDAR=GREGORIA835DATA
CHENZWPART_LOG_CHENZWNOPART_LOG_060TO_DATE('2013-10-0100:
00:
00','SYYYY-MM-DDHH24:
MI:
SS','NLS_CALENDAR=GREGORIA836DATA
CHENZWPART_LOG_CHENZWNOPART_LOG_070MAXVALUE87DATA
7rowsselected
从上面的结果可以看到,如果我们希望找到7、8月份的数据,就可以根据分区上限定位到PART_LOG_05分区。
最后,我们可以通过查询数据字典USER_SEGMENTS来查看分区表占用的磁盘空间信息,如下:
SELECTT.SEGMENT_NAMEAS"段名",
T.PARTITION_NAMEAS"分区名",
T.SEGMENT_TYPEAS"分区类型",
T.BYTES/POWER(1024,2)||'M'AS"分区大小",
T.TABLESPACE_NAMEAS"表空间"
FROMUSER_SEGMENTST
WHERET.SEGMENT_NAMEIN('PART_LOG_CHENZW');
得到的结果如下:
段名分区名分区类型分区大小表空间
---------------------------------------------------------------
PART_LOG_CHENZWPART_LOG_01TABLEPARTITION.0625MDATA
PART_LOG_CHENZWPART_LOG_02TABLEPARTITION.5625MDATA
PART_LOG_CHENZWPART_LOG_03TABLEPARTITION.5625MDATA
PART_LOG_CHENZWPART_LOG_04TABLEPARTITION.5625MDATA
PART_LOG_CHENZWPART_LOG_05TABLEPARTITION.625MDATA
PART_LOG_CHENZWPART_LOG_06TABLEPARTITION.3125MDATA
PART_LOG_CHENZWPART_LOG_07TABLEPARTITION.875MDATA
7rowsselected
2)列表分区(partitionbylist)
假设我们现在只有四种类型的10W本图书,分别为0教育类、1IT类、2人文类、3社科类,只有这四种情况,我们就可以通过图书的类型进行分区。
通常情况下,如果你的数据中的某一项是可以被枚举的,那么,此列就可以用作列表分区的分区字段。
DROPTABLEPART_BOOK_CHENZWPURGE;
CREATETABLEPART_BOOK_CHENZW(
BOOK_IDNUMBER(20)PRIMARYKEY,
BOOK_DATEDATE,
BOOK_TYPENUMBER
(2)NOTNULL,
BOOK_DESCVARCHAR2(20)
)
PARTITIONBYLIST(BOOK_TYPE)
(
PARTITIONPART_BOOK_01VALUES(0)TABLESPACEDATA,
PARTITIONPART_BOOK_02VALUES
(1)TABLESPACEDATA,
PARTITIONPART_BOOK_03VALUES
(2)TABLESPACEDATA,
PARTITIONPART_BOOK_04VALUES(3)TABLESPACEDATA
);
下面的脚本用于生成相应的数据:
INSERTINTOPART_BOOK_CHENZW
(BOOK_ID,BOOK_DATE,BOOK_TYPE,BOOK_DESC)
SELECTLEVEL,
TO_DATE('2013-01-01','YYYY-MM-DD')+
NUMTODSINTERVAL(CEIL(DBMS_RANDOM.VALUE(0,365)),'DAY'),
MOD(LEVEL,4),
LEVEL||'DESC'
FROMDUAL
CONNECTBYLEVEL<=100000;
3)散列分区(partitionbyhash)
个人觉着散列分区的更多的作用在于分散数据,通过将数据均匀分布从而规避I/O瓶颈,但是这个在平时的生产中确实比较少用到,所以,建议仅仅作为了解了。
DROPTABLEPART_BOOK_CHENZWPURGE;
CREATETABLEPART_BOOK_CHENZW(
BOOK_IDNUMBER(20)PRIMARYKEY,
BOOK_DATEDATE,
BOOK_TYPENUMBER
(2)NOTNULL,
BOOK_DESCVARCHAR2(20)
)
PARTITIONBYHASH(BOOK_ID)
(
PARTITIONPART_BOOK_01TABLESPACEDATA,
PARTITIONPART_BOOK_02TABLESPACEDATA,
PARTITIONPART_BOOK_03TABLESPACEDATA,
PARTITIONPART_BOOK_04TABLESPACEDATA
);
INSERTINTOPART_BOOK_CHENZW
(BOOK_ID,BOOK_DATE,BOOK_TYPE,BOOK_DESC)
SELECTLEVEL,
TO_DATE('2013-01-01','YYYY-MM-DD')+
NUMTODSINTERVAL(CEIL(DBMS_RANDOM.VALUE(0,365)),'DAY'),
MOD(LEVEL,4),
LEVEL||'DESC'
FROMDUAL
CONNECTBYLEVEL<=100000;
4)组合分区(partitionbyxxxsubpartitionbyxxx)
假如我们现在有10W本月刊类杂志提供给消费者查看和购买,我们如何做分区合适呢?
首先我们可以先将图书根据种类进行分区,然后再对每个分区进行月份的分区,这样对于大量的图书而言,我们就可以根据实际的业务需要,将一大堆数据通过分区拆解为若干个小标进行管理,从而降低了管理的粒度,做到“精细化管理”。
下面是一个进行组合分区的例子:
--删除测试表
DROPTABLEPART_BOOK_CHENZWPURGE;
--创建列表-范围组合分区
CREATETABLEPART_BOOK_CHENZW(
BOOK_IDNUMBER(20)PRIMARYKEY,
BOOK_DATEDATE,
BOOK_TYPENUMBER
(2)NOTNULL,
BOOK_DESCVARCHAR2(20)
)
PARTITIONBYLIST(BOOK_TYPE)
SUBPARTITIONBYRANGE(BOOK_DATE)
SUBPARTITIONTEMPLATE
(
SUBPARTITIONPART_LOG_01VALUESLESSTHAN(TO_DATE('2013-01-01','YYYY-MM-DD'))TABLESPACEDATA,
SUBPARTITIONPART_LOG_02VALUESLESSTHAN(TO_DATE('2013-03-01','YYYY-MM-DD'))TABLESPACEDATA,
SUBPARTITIONPART_LOG_03VALUESLESSTHAN(TO_DATE('2013-05-01','YYYY-MM-DD'))TABLESPACEDATA,
SUBPARTITIONPART_LOG_04VALUESLESSTHAN(TO_DATE('2013-07-01','YYYY-MM-DD'))TABLESPACEDATA,
SUBPARTITIONPART_LOG_05VALUESLESSTHAN(TO_DATE('2013-09-01','YYYY-MM-DD'))TABLESPACEDATA,
SUBPARTITIONPART_LOG_06VALUESLESSTHAN(TO_DATE('2013-10-01','YYYY-MM-DD'))TABLESPACEDATA,
SUBPARTITIONPART_LOG_07VALUESLESSTHAN(MAXVALUE)TABLESPACEDATA
)
(
P
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 什么是 Oracle 分区表