Oracle 数据表分区的策略

  • 来源: 互联网 作者: 若水   2008-04-23/13:43
  • 本文描述通过统计分析出医院信息系统需分区的表,对需分区的表选择分区键,即找出包括在你的分区键中的列(表的属性),对大型数据的管理比较有意义, 本文的工作在Oracle8.1.6下实现。

    Oracle虽然是一个大型的DBMS,但如果不对记录比较多的表进行处理,仍然发挥不了Oracle管理大型数据的强大功能,因此对某些表进行分区,具有如下优点:

    分区表中每个分区可以在逻辑上认为是一个独立的对象;

    可以在一个表中的一个或多个分区上进行如删除、移动、析分等维护操作,而不会影响其它分区,具有分区独立性;

    如果选择合适的分区策略,会大大的加快数据的查询速度。

    一 找出需分区的表

    本节描述通过统计分析出医院His系统需分区的表,对需分区的表找出包括在你的分区键中的列(表的属性),即选择分区键。

    1、基于访问频度找出需分区的表

    Oracle8i允许访问数据库中的审核信息,借助于收集的审核信息,设计者能够确定哪些表的数据是真正最频繁访问的,即找出那些表,需要进行分区。

    打开审核:在作为SYS或SYSSTEM登录到数据库后,动行如下脚本,打开对象的审核功能。

    set echo off feed off ver off pages 0
    spool audon.sql
    select ’audit select on ’||owner||’.’||object_name||’ by
    access;’
    from dba_objects
    where object_type in (’VIEW’,’TABLE’) and owner in
    (’ORDADM’);
    spool off
    set echo on feed on ver on

    这些代码的运行将产生“audon.sql”的输出文件,它包含下面清单中所示格式的语句

    audit select on ORDADM.DOCTOR_ORDERS by access;
    audit select on ORDADM.GROUP_ORDER_ITEMS by access;
    audit select on ORDADM.GROUP_ORDER_MASTER by access;
    audit select on ORDADM.ORDERS by access;
    audit select on ORDADM.ORDERS_COSTS by access;
    audit select on ORDADM.ORDERS_SHEET_IMAGE by access;
    audit select on ORDADM.VITAL_SIGNS_REC by access;

    使用命令@audon.sql激活上述代码以打开审核功能收集收集审核信息,建立一个表以保存概要信息:

    create table aud_summary (
    obj_name varchar2(30),
    owner varchar2(30),
    hits number);

    将审核信息从dba_audit_object表中取出并装入概要表中:

    insert into aud_summary
    select obj_name,owner,count(*)
    from dba_audit_object
    group by obj_name,owner;

    关闭审核:

    set echo off feed off ver off pages 0
    spool audoff.sql
    select ’noaudit select on ’||owner||’.’||object_name|| ’
    by access;’
    from dba_objects
    where object_type in (’VIEW’,’TABLE’) and owner in
    (’ORDADM’);
    spool off
    set echo on feed on ver on

    这些代码的运行将产生“audoff.sql”的输出文件。

    使用命令@ audoff.sql激活上述代码以关闭上述对象的审核功能。

    清除审核信息:

    delete sys.aud$

    分析审核信息

    col obj_name form a30
    col owner form a20
    col hits form 99,990
    selec obj_name,owner,hits from aud_summary;
    OBJ_NAME OWNER COUNT(*)
    ----------- ------------- ----------
    DOCTOR_ORDERS ORDADM 30309
    DRUG_STOCK PHARMACY 11094
    GROUP_ORDER_ITEMS ORDADM 1030
    GROUP_ORDER_MASTER ORDADM 1196
    ORDERS ORDADM 40421
    ORDERS_COSTS ORDADM 10109

    以上是HIS系统临床医嘱部分24小时内对表的访问情况,从上面的查询得表1-1。

    表1-1

    行数 命中率
    doctor_orders 2052709 30309
    drug_stock 2511 11094
    group_order_item 3800 1030
    group_order_master 186 1196
    orders 1633010 40421
    orders_costs 2403214 10109
    #p#分页标题#e#
    group_order_master( 医嘱套攴主记录) 、group_order_item(医嘱套攴明细), 表的行数比较少,不适合分区;drug_stock(药品库存)虽然存取频率比较高,但表的行数比较少,因此也不适合分区。我们选择表的行数比较多、存取频率比较高的表作分区处理,如 doctor_orders、orders、orders_costs,考虑到doctor_orders是医生工作站上医生开的医嘱,orders是由doctor_orders生成、护士工作站上执行的医嘱,两个表结构类似,而医嘱与药品、卫生材料、计费联系比较密切的是Orders,因此重点介绍对表orders的处理。

    2、基于列值选择分区键

    使用Sql*plus下用命令Analyze收集末分区表的统计信息,按照Oracle推荐的取样20%进行分析,并将统计结果保存在数据字典中。

    Analyze table ORDADM.ORDERS estimate statistics
    sample 20 percent;

    对DBA_TAB_COLUMNS数据字典视图进行查询

    产生表1-2

    select table_name,column_name,num_distinct
    from DBA_TAB_COLUMNS
    where owner like ’ORDADM’;

    表1-2

    不同的值
    PATIENT_ID 28720
    VISIT_ID 2
    ORDER_NO 395
    ORDER_SUB_NO 10
    ORDER_CLASS 9
    ORDER_CODE 825
    ORDER_TEXT 1551
    ORDERING_DEPT 15
    START_DATE_TIME 1194176
    STOP_DATE_TIME 636798
       


    从表1-2中,我们可以看到欲分区表的各个候选分区键的分布频谱,ORDER_CODE(医嘱代码)键值没有出现一种均匀分布,用它作分区键,明显不合适;

    ORDER_CLASS(医嘱类别代码)、ORDERING_DEPT(开医嘱科室代码),键值出现均匀分布,如用它的各个键值作基于范围的分区,每个分区具有的记录数比较均匀,但这种方法对于每天增加上万条记录的表来看,显然不是最优的。如果选用START_DATE_TIME(医嘱开始时间)建立范围分区,每月的数据建立一个分区,在每个分区内基于ORDERING_DEPT建立散列子分区,每月的数据形成一个组合分区,会使每个分区的记录数分布均匀、查询速度提高、易于备份和删除。因为大多数的统计和查询是在一个月的范围内,而且从实际的查询效果看,跨月和跨年数据的统计和查询速度,也比未分区的时候大大缩短,效果非常明显。


    评论 {{userinfo.comments}}

    {{money}}

    {{question.question}}

    A {{question.A}}
    B {{question.B}}
    C {{question.C}}
    D {{question.D}}
    提交

    驱动号 更多