4、表的设计

1、查看redo size
     select a.name, b.value 
     from v$statname a, v$mystat b
     where a.STATISTIC# = b.STATISTIC#
     and a.NAME = 'redo size';
     在执行某个sql前执行一下得到结果A,在执行一个sql之后,再次执行上面的脚本,得到结果B
     B - A 就是 执行的sql带来的回滚日志开销大小
     
2、因为delete操作产生的undo操作最多,且undo本身也需要redo来保证安全性,
     所以在insert、update、delete三个操作中,delete操作的undo量和redo量是最多的,开销最大
 
3、delete操作虽然删除了很多记录,但是block并没有被回收,全部是空块
     而truncate操作则是回收了block
     所以delete是无法释放空间的
     另外,delete是DML操作,truncate是DDL操作
 
     另外,大量的delete之后,再次insert时,会优先插入那先空块
 
4、大表检索的优化思路
     表就是段,要使检索的效率提升,就要使遍历该segment的路径最短(即访问的block最少)
     保持路径短的方式有:
     1)索引
          查询时先访问索引段(索引是独立的段,其中存储了索引段与表段的映射关系)
          如果一个查询能只从索引段中获取所有返回数据,则性能最优
          如果需要根据索引段信息返回表段获取数据,性能次之
          如果使用不上索引段,性能再次之。
          (不过索引建立的不好的话,也是灾难性的问题)
          针对一个场景:在表T上建立了索引IDX_ID,
          select id from t 的 开销比 select * from t 要少很多,
          但是如何使上述两个脚本的开销一致呢?( 索引组织表
     2)分区
          根据关键维度将数据进行分区存储和管理
          既能减少block的访问路径,还能高效的清理数据
 
5、数据有序插入难以有序读出来
     插入N条数据后,删除中间的一条数据,然后再插入一条数据
     然后select,发现数据不一定是按顺序来的
     因为后面insert的数据insert到数据被删除的block上了
     而要是继续有序,则必须使用order by 
     而众所周知,order by是非常耗资源和性能的
     避免order by的方式有两个:
     1)在排序列上建立索引
     2)将表改造为  有序散列聚簇表
 
6、分区表
     四个大类:范围分区(最常用)、列表分区、散列分区(hash)、组合分区(主分区+从分区方式)
     分为多少个区,就会产生多少个段(segment)
     分区过多的话,oracle需要管理过多的段,在操作分区时容易引起内部大量的递归调用等等,所以会产生比较高的代价
     建议单表在100W以上数据时才进行分区
     特性:
     1)高效分区消除,即数据查询范围比较集中,减少逻辑读
     2)局部数据清理更快捷(允许的情况下可以直接使用truncate以释放空间)
     3)分区数据转移:将某个分区的数据与一张中间表进行交换
          alter table 分区表名称 exchange partition 具体的某一个分区名 with table 中间表
          示例:alter table range_part_tab exchange partition p8 with table mid_tab;
                    将分区表 range_part_tab 的 分区p8 中的数据与 mid_tab 进行交换
                    再次执行这个sql,数据又会被交换回来
     4)分区切割
          alter table 分区表名称  split  partition 具体的某一个分区名  at (分区界限)  into (partition 切割后的前一个分区名, partition 切割后的后一个分区名)
     5)合并分区
          alter table 分区表名称 merge partitions 分区1,分区2 into partition 合并后的分区名
     6)新增分区
          当追加的分区界限比最后一个分区的界限低时,无法新增,需要先想办法将大于该界限的分区删除
          alter table 分区表 add partition 分区名 values less then (分区界限)
     7)删除分区
          alter table 分区表 drop partition 分区名;

猜你喜欢

转载自weiluo2012.iteye.com/blog/2195273