表的设计

:普通表的不足

  1)表的更新有日志开销

  2)表的DELETE不彻底 ()

  3)大表查询慢

  4)索引表读开销大

1:日志开销 

--查看产生多少redo 日志 

  1)

  col name format a30

  select a.name,b.value

  from v$statname a,v$mystat b

  where a.statistic#=b.statistic#

  and a.name='redo size';

  2)通过执行计划查看

      set autotrace on


      alter table t nologging;

      create table t as select * from dba_objects where 1=2;

      insert into t select * from dba_objects ;


      insert /*+ append,nologging*/ into t select * from dba_objects ;

      insert /*+ append nologging */ into t select * from dba_objects;

      alter table t logging;

--查看普通表是否为nologging     

    col OWNER format a20

    col table_name format a30 

    select OWNER,TABLE_NAME,logging from dba_tables where TABLE_NAME='T';


    Noarchivelog模式下,对于常规表的insert append只产生少量redo

    archivelog 常规表的insert append产生和insert同样的redo此时的insert append实际上并不会有性能提高.

但是此时的append是生效了的


--优化建议

    不考虑空间和数据安全(性能和安全需要相互妥协):

    1) alter table t nologging

    2) 以append 方式插入数据

2:删除不彻底

  delete是最消耗性能的操作:产生UNDO最多,同时UNDO也需要REDO保护,delete 产生的REDO最大

  creater table delete_t as select * from dba_objects;

  set autotrace on

  select count(1) from delete_t;

  delete from delete_t;

  select count(1) from delete_t;

  truncate table delete_t;

  select count(1) from delete_t;

  insert into delete_t select * from dba_objects;

  delete from delete_t;

  truncate table delete_t;


  优化方法:分区表

3:大表查询慢

  全表扫描

  create table big_t as select * from dba_objects;

  insert into  big_t select * from big_t;

  set timing on

  set autotrace on

  EXEC DBMS_STATS.gather_table_stats('sys','big_t');

  select object_name from big_t where object_id=50;

  drop index big_object_id;

  create index big_object_id on big_t(object_id);

  解决办法:减少访问路径

  1)分区表

  2)索引



4: 索引表读开销大

    set autotrace on

    select object_name from big_t where object_id=50;

    create index big_object_id on big_t(object_id,object_name);

    select object_name from big_t where object_id=50;



5: 分区表设计


  分区表类型:范围分区、列表分区、哈希分区、组合分区

          1)范围分区

            create table PART_T_RANGE partition by range(object_id)

                    (

                    partition p1 values less than (10000),

                    partition p2 values less than (20000),         

                    partition p3 values less than (30000),             

                    partition p4 values less than (40000),

                    partition p5 values less than (50000),

                    partition p6 values less than (60000),

                    partition p7 values less than (70000),

                  --partition p8 values less than (80000),

                    partition p_max values less than (maxvalue)

                    )

                    as select * from dba_objects;


            create table BIG_T as select * from dba_objects ;



            select * from dba_segments where segment_name in ('PART_T_RANGE','BIG_T');


          2)列表分区

              create table PART_T_LIST

                  partition by list(OBJECT_TYPE)   

                      (

                      partition p_SYNONYM values ('SYNONYM'),

                      partition p_VIEW values ('VIEW'),

                      partition p_other values (default)

                      )

                      as select * from dba_objects; 


              select * from dba_segments where segment_name in ('PART_T_RANGE','BIG_T','PART_T_LIST'); 

              select * from dba_segments where owner='WEISI' 


          3)散列分区(HASH 分区)

            create table PART_T_HASH

                    partition by hash(object_id)

                    partitions  10

                    as select * from dba_objects;   


                  select * from dba_segments where segment_name='PART_T_HASH'


          4)组合分区

            4.1范围-列表

                create table PART_T_RANGE_LIST

                      partition by range(object_id)

                        subpartition by list(object_type)

                        subpartition template

                          ( subpartition  p_SYNONYM values ('SYNONYM'),

                            subpartition p_VIEW    values ('VIEW'),

                            subpartition p_other  values (default)

                          )

                        (

                        partition p1 values less than (10000),

                        partition p2 values less than (20000),         

                        partition p3 values less than (30000),             

                        partition p4 values less than (40000),

                        partition p5 values less than (50000),

                        partition p6 values less than (60000),

                        partition p7 values less than (70000),

                        partition p8 values less than (80000),

                        partition p_max values less than (maxvalue)

                        )

                        as select * from dba_objects;   



                    select * from dba_segments where segment_name in ('PART_T_RANGE','BIG_T','PART_T_LIST','PART_T_RANGE_LIST'); 




  分区表原理:  select * from dba_segments where segment_name in ('PART_T_RANGE','BIG_T','PART_T_LIST','PART_T_RANGE_LIST');

                将一个大的对象切割成一个小对象


  分表表重要特性 :

        1)高效消除分区

            EXEC DBMS_STATS.gather_table_stats('SYS','PART_T_RANGE');

            range

            set linesize 200

            set autotrace traceonly

            set timing on

            select * from part_t_range where object_id < 50000 and object_id > 30000;

            create table normal_t as select * from dba_objects;   

            select * from normal_t  where object_id < 50000 and object_id > 30000; 


            select * from part_t_range where object_id < 50000 and object_id > 30000 and object_type='SYNONYM';

            select * from part_t_range_list where object_id < 50000 and object_id > 30000 and object_type='SYNONYM';

            select * from norm_t where object_id < 50000 and object_id > 30000 and object_type='SYNONYM';


        2) 多样的分区操作

            2.1 删除分区

                delete 无法释放空间

                truncate 有效的释放空间

                PART_T_RANGE_LIST

                alter table PART_T_range truncate partition P1;

                delete normal_t where object_id<10000;

            2.2  分区转移

                select count(1) from part_t_list where object_type='VIEW'; 

                select count(1) from part_t_list partition(p_VIEW);

                create table change_t as select * from dba_objects where 1=2;

                select count(1) from change_t;

                alter table part_t_list exchange partition P_VIEW with table change_t;

                select count(1) from part_t_list where object_type='VIEW'; 

                select count(1) from change_t;

                insert into change_t select * from dba_objects where rownum< 100;

                commit;

                alter table part_t_list exchange partition P_VIEW with table change_t;


          3.3 分区切割     

                select object_type from part_t_list partition(p_other) group by object_type ;

                select object_type from part_t_list partition(p_other) where object_type='INDEX'group by object_type ;

                alter table part_t_list split partition p_other values('INDEX') into(partition p_index,partition p_other);

                alter table part_t_range split partition p_max at(71000) into(partition p_71000,partition p_max);

                select object_id from part_t_range partition(p_71000);

                select * from dba_segments where segment_name in ('PART_T_LIST','PART_T_RANGE') ;               

          3.4  分区合并

                select count(1) from part_t_range partition(p7);

                select count(1) from part_t_range partition(p_max);


                alter table part_t_range merge partitions p7, p_max into partition p_max;

                alter table part_t_list  merge partitions p_index,p_other into partition p_other;

                select * from dba_segments where segment_name in ('PART_T_LIST','PART_T_RANGE') ;

          3.5  分区增与删

                alter table part_t_range add partition p_72000 values less than (72000);

                select OBJECT_ID from part_t_range partition(p_71000);

          3.5  分区改名

                alter table part_t_range rename partition p_7100 to p_71000;

                alter table part_t_range1 rename to part_t_range;


            EXEC DBMS_STATS.gather_table_stats('SYS','PART_T_RANGE');


6:  分区索引

    1)全局索引   

        创建全局索引

        create index index_range on part_t_range(object_id);

        select segment_name,partition_name,segment_type,bytes from dba_segments where segment_name='INDEX_RANGE';


    2) 局部索引

        创建局部索引

        create index index_list_local on part_t_list(object_type) local; 

        select segment_name,partition_name,segment_type,bytes from dba_segments where segment_name='INDEX_LIST_LOCAL';

7: 分区索引注意事项

    1:索引失效

      select index_name,status from dba_indexes where index_name in ('INDEX_RANGE','INDEX_LIST_LOCAL');

      select index_name,partition_name,status from dba_ind_partitions where index_name='INDEX_LIST_LOCAL';

      alter table part_t_range truncate partition p2;

      select count(1) from part_t_range partition(p2); 

      alter table part_t_list truncate partition p_view;

      select count(1) from part_t_list partition(p_view); 

      alter index index_range rebuild; 

      select index_name,status from dba_indexes where index_name in ('INDEX_RANGE','INDEX_LIST_LOCAL');

  2:本地索引并不是一定是最好的

      create index index_range_list on PART_T_RANGE_LIST(object_name) local;

      create index index_norm  on norm_t(object_name);

      set autotrace traceonly

      set linesize 300

      select * from part_t_range_list where object_name='PK_DEPT';

      select * from norm_t where object_name='PK_DEPT';



  3:无法应用分区条件

      set autotrace traceonly

      set linesize 300

      select * from part_t_range_list where object_name='PK_DEPT';

      select * from part_t_range_list where object_name='PK_DEPT_WEISI';

      select * from part_t_range_list where object_name='PK_DEPT_WEISI' and object_id<1000 and object_type='VIEW';

      select * from norm_t where object_name='PK_DEPT_WEISI' and object_id<1000 and object_type='VIEW';

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,548评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,497评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,990评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,618评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,618评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,246评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,819评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,725评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,268评论 1 320
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,356评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,488评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,181评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,862评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,331评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,445评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,897评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,500评论 2 359

推荐阅读更多精彩内容