本文描述通过统计分析出医院信息系统需分区的表对需分区的表选择分区键即找出包括在你的分区键中的列(表的属性)对大型数据的管理比较有意义 本文的工作在Oracle下实现
Oracle虽然是一个大型的DBMS但如果不对记录比较多的表进行处理仍然发挥不了Oracle管理大型数据的强大功能因此对某些表进行分区具有如下优点
分区表中每个分区可以在逻辑上认为是一个独立的对象
可以在一个表中的一个或多个分区上进行如删除移动析分等维护操作而不会影响其它分区具有分区独立性
如果选择合适的分区策略会大大的加快数据的查询速度
一 找出需分区的表
本节描述通过统计分析出医院His系统需分区的表对需分区的表找出包括在你的分区键中的列(表的属性)即选择分区键
基于访问频度找出需分区的表
Oraclei允许访问数据库中的审核信息借助于收集的审核信息设计者能够确定哪些表的数据是真正最频繁访问的即找出那些表需要进行分区
打开审核在作为SYS或SYSSTEM登录到数据库后动行如下脚本打开对象的审核功能
set echo off feed off ver off pages
spool audonsql
select audit select on ||owner||||object_name|| by
access;
from dba_objects
where object_type in (VIEWTABLE) and owner in
(ORDADM);
spool off
set echo on feed on ver on
这些代码的运行将产生audonsql的输出文件它包含下面清单中所示格式的语句
audit select on ORDADMDOCTOR_ORDERS by access;
audit select on ORDADMGROUP_ORDER_ITEMS by access;
audit select on ORDADMGROUP_ORDER_MASTER by access;
audit select on ORDADMORDERS by access;
audit select on ORDADMORDERS_COSTS by access;
audit select on ORDADMORDERS_SHEET_IMAGE by access;
audit select on ORDADMVITAL_SIGNS_REC by access;
使用命令@audonsql激活上述代码以打开审核功能收集收集审核信息建立一个表以保存概要信息
create table aud_summary (
obj_name varchar()
owner varchar()
hits number);
将审核信息从dba_audit_object表中取出并装入概要表中
insert into aud_summary
select obj_nameownercount(*)
from dba_audit_object
group by obj_nameowner;
关闭审核
set echo off feed off ver off pages
spool audoffsql
select noaudit select on ||owner||||object_name||
by access;
from dba_objects
where object_type in (VIEWTABLE) and owner in
(ORDADM);
spool off
set echo on feed on ver on
这些代码的运行将产生audoffsql的输出文件
使用命令@ audoffsql激活上述代码以关闭上述对象的审核功能
清除审核信息
delete sysaud$
分析审核信息
col obj_name form a
col owner form a
col hits form
selec obj_nameownerhits from aud_summary;
OBJ_NAME OWNER COUNT(*)
DOCTOR_ORDERS ORDADM
DRUG_STOCK PHarmACY
GROUP_ORDER_ITEMS ORDADM
GROUP_ORDER_MASTER ORDADM
ORDERS ORDADM
ORDERS_COSTS ORDADM
以上是HIS系统临床医嘱部分小时内对表的访问情况从上面的查询得表
表
group_order_master( 医嘱套攴主记录) group_order_item(医嘱套攴明细) 表的行数比较少不适合分区drug_stock(药品库存)虽然存取频率比较高但表的行数比较少因此也不适合分区我们选择表的行数比较多存取频率比较高的表作分区处理如 doctor_ordersordersorders_costs考虑到doctor_orders是医生工作站上医生开的医嘱orders是由doctor_orders生成护士工作站上执行的医嘱两个表结构类似而医嘱与药品卫生材料计费联系比较密切的是Orders因此重点介绍对表orders的处理
基于列值选择分区键
使用Sql*plus下用命令Analyze收集末分区表的统计信息按照Oracle推荐的取样%进行分析并将统计结果保存在数据字典中
Analyze table ORDADMORDERS estimate statistics
sample percent;
对DBA_TAB_COLUMNS数据字典视图进行查询
产生表
select table_namecolumn_namenum_distinct
from DBA_TAB_COLUMNS
where owner like ORDADM;
表
从表中我们可以看到欲分区表的各个候选分区键的分布频谱ORDER_CODE(医嘱代码)键值没有出现一种均匀分布用它作分区键明显不合适
ORDER_CLASS(医嘱类别代码)ORDERING_DEPT(开医嘱科室代码)键值出现均匀分布如用它的各个键值作基于范围的分区每个分区具有的记录数比较均匀但这种方法对于每天增加上万条记录的表来看显然不是最优的如果选用START_DATE_TIME(医嘱开始时间)建立范围分区每月的数据建立一个分区在每个分区内基于ORDERING_DEPT建立散列子分区每月的数据形成一个组合分区会使每个分区的记录数分布均匀查询速度提高易于备份和删除因为大多数的统计和查询是在一个月的范围内而且从实际的查询效果看跨月和跨年数据的统计和查询速度也比未分区的时候大大缩短效果非常明显
二 分区表的定义
Create Table orders (
PATIENT_ID varchar() not null ORDER_NO number() ORDER_SUB_NO number()
ORDER_CLASS char()
ORDER_TEXT varchar()
ORDER_CODE varchar()
START_DATE_TIME date
STOP_DATE_TIME date
ORDERING_DEPT varchar()
storage (initial M next M)
PARTITION BY RANGE(START_DATE_TIME)
SUBPARTITION BY HASH(ORDER_CODE)
SUBPARTITIONS STORE IN (ordersub ordersub ordersub )
(PARTITION orders VALUES LESS THAN (to_date( :: yyyymmdd hh:mi:ss))
tablespace Tsp_Orders
PARTITION orders
VALUES LESS THAN (to_date( :: yyyymmdd hh:mi:ss))
tablespace Tsp_Orders
PARTITION orders
VALUES LESS THAN (to_date( :: yyyymmdd hh:mi:ss))
tablespace Tsp_Orders
PARTITION orders
VALUES LESS THAN (to_date( :: yyyymmdd hh:mi:ss))
tablespace Tsp_Orders
(SUBPARTITION ordersub TABLESPACE Tsp_Orders SUBPARTITION ordersub TABLESPACE Tsp_Orders
SUBPARTITION ordersub TABLESPACE Tsp_Orders));
在建立的Orders表中按每月一个分区从年月开始年月止共个分区 PARTITION BY RANGE(START_DATE_TIME) 子句表示用表的START_DATE_TIME属性建立范围分区具体的每个分区名时间范围在PARTITION子句定义SUBPARTITION BY HASH(ORDER_CODE)子句表示用表的ORDER_CODE 属性在每个分区下建立散列子分区具体的每个子分区名所在表空间在UBPARTITION子句定义
用下面ALTER TABLE数据定义语句为Orders建立约束和索引
ALTER TABLE Orders ADD CONSTRAINT Pk_Orders KEY (Patient_id
Visit_idOrder_noOrder_sub_no) USING INDEX PCTFREE TABLESPACE Tsp_Orders;
表是用select count(*) from orders partition (分区名)语句查询出的名分区的记录数
表
三 分区表的维护操作
增添分区
Alter Table orders Add partition orders
Aalues less (to_date( ::yyyymmdd hh: mi:ss))
Tablespace Tsp_Orders;
删除分区
Alter Table table_name Drop Partition partition_name;
裁断分区:
Alter Table table_name Truncate Partition partition_name Storage;
Oracle数据表分区小知识
为了简化数据库大表的管理O r a c l e 及以后版本推出了分区选项分区将表分离在若干不同的表空间上用分而