热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

Oracle分区和性能简析

Oracle分区和性能简析理论上,我们进行表分区都是为了提升性能,加快查询速度。但是有的时候,不但不能加快查询速度,反而拖累的查询速度。下面举的一个例子就是这样的:www.2cto.com假设某一个表是...SyntaxHighlighter.all();

Oracle分区和性能简析
 
  理论上,我们进行表分区都是为了提升性能,加快查询速度。但是有的时候,不但不能加快查询速度,反而拖累的查询速度。下面举的一个例子就是这样的:
   www.2cto.com  
      假设某一个表是按照主键散列分区,创建表如下所示:
 
Sql代码  
create table t  
 ( OWNER, OBJECT_NAME, SUBOBJECT_NAME, OBJECT_ID, DATA_OBJECT_ID,  
 OBJECT_TYPE, CREATED, LAST_DDL_TIME, TIMESTAMP, STATUS,  
 TEMPORARY, GENERATED, SECONDARY )  
 partition by hash(object_id)  
 partitions 16  
 as  
 select * from all_objects;  
      我们经常要在表上面,根据owner 或者 object_type,object_name 或者owner, object_type,object_name进行查询。于是我们想到在这三列上建立一个局部索引。如下所示:
 
Sql代码  
create index t_idx  
on t(owner,object_type,object_name)  
LOCAL  
      运行一个存储过程收集cpu耗用等信息:
 
Sql代码  
begin  
 dbms_stats.gather_table_stats  
 ( user, 'T', cascade=>true);  
 end;  
 /  
      改变几个会话属性,便于允许TKPROF
 
Sql代码  
alter session set timed_statistics=true;  
alter session set events '10046 trace name context forever,level 12';  
      执行如下SQL语句:
 
Sql代码  
select * from t where owner='SCOTT' and object_type = 'TABLE' and object_name = 'EMP';  
select * from all_objects where owner='SCOTT' and object_type = 'TABLE' and object_name = 'EMP';  
      查看TKPROF记录的性能日志位置:
 
Sql代码  
select rtrim(c.value,'\') ||'\'||d.instance_name||  
    '_ora_' ||ltrim(to_char(a.spid))||'.trc'  
    from v$process a,v$session b,v$parameter c,v$instance d  
    where a.addr=b.paddr  
    and b.audsid =sys_context('userenv','sessionid')  
    and c.name='user_dump_dest';  
      假如看到这样的输出:D:\ORACLELWS\PRODUCT\10.2.0\ADMIN\ORCL\UDUMP\orcl_ora_5928.trc
      另外打开一个命令行,输入如下命令解析日志文件
 
Sql代码  
tkprof D:\ORACLELWS\PRODUCT\10.2.0\ADMIN\ORCL\UDUMP\orcl_ora_5928.trc  
      弹出一个output = 要你输入解析日志之后的文件存放的目录,可以填写c:\tk.prof ,必须prof后缀。
      这个时候我们可以用记事本打开tk.prof文件查看上述两条查询SQL语句的性能,我的机器上查看的结果如下
 
Sql代码  
select *   
from  
 t where owner='SCOTT' and object_type = 'TABLE' and object_name = 'EMP'  
  
call     count       cpu    elapsed       disk      query    current        rows  
------- ------  -------- ---------- ---------- ---------- ----------  ----------  
Parse        1      0.00       0.00          0          0          0           0  
Execute      1      0.00       0.00          0          0          0           0  
Fetch        2      0.00       0.00          0         34          0           1  
------- ------  -------- ---------- ---------- ---------- ----------  ----------  
total        4      0.00       0.00          0         34          0           1  
  
select *   
from  
 all_objects where owner='SCOTT' and object_type = 'TABLE' and object_name =   
  'EMP'  
  
call     count       cpu    elapsed       disk      query    current        rows  
------- ------  -------- ---------- ---------- ---------- ----------  ----------  
Parse        1      0.01       0.01          0          0          0           0  
Execute      1      0.00       0.00          0          0          0           0  
Fetch        2      0.00       0.00          0          8          0           1  
------- ------  -------- ---------- ---------- ---------- ----------  ----------  
total        4      0.01       0.01          0          8          0           1  
     各个字段的意思可以百度一下,我们发现query字段分区是34,不分区是8。query代表I/O操作次数,分区反而增加了I/O操作次数,费力不讨好。这是因为查找条件字段没有包含分区表的分区键,导致每一个表分区都要扫描,也就是每一个索引分区都要扫描,还不如全表扫描来得快。  www.2cto.com  
     如果不创建局部索引,而是建立一个全局索引。效率跟不分区差不多,创建局部分区的sql换成:
 
Sql代码  
create index t_idx  
 on t(owner,object_type,object_name)  
 global  
 partition by hash(owner)  
 partitions 16  
   
    其实,对于OLTP系统,分区对于获取数据没有什么正面影响(基本不能提高查询速度)。相反,我们还有非常小心避免产生负面影响,比如上面那个例子。但是对于高度并发修改的环境,分区则可能提供显著的效果,因为分区避免了数据的冲突,你修改这个分区,他修改那个分区,大大降低了发生冲突的可能性。因此,不要盲目使用分区,分区不一定能够提高性能。
 

推荐阅读
author-avatar
_戒咗微博地_100
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有