首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > 其他数据库 >

Oracle 分区跟性能

2012-11-13 
Oracle 分区和性能?? ? ? 理论上,我们进行表分区都是为了提升性能,加快查询速度。但是有的时候,不但不能加

Oracle 分区和性能

?

? ? ? 理论上,我们进行表分区都是为了提升性能,加快查询速度。但是有的时候,不但不能加快查询速度,反而拖累的查询速度。下面举的一个例子就是这样的:

?

? ? ? 假设某一个表是按照主键散列分区,创建表如下所示:

?

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进行查询。于是我们想到在这三列上建立一个局部索引。如下所示:

?

 create index t_idx on t(owner,object_type,object_name) LOCAL

? ? ? 运行一个存储过程收集cpu耗用等信息:

?

begin dbms_stats.gather_table_stats ( user, 'T', cascade=>true); end; /

?

? ? ? 改变几个会话属性,便于允许TKPROF

?

alter session set timed_statistics=true;alter session set events '10046 trace name context forever,level 12';

? ? ? 执行如下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记录的性能日志位置:

?

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

? ? ? 另外打开一个命令行,输入如下命令解析日志文件

?

tkprof D:\ORACLELWS\PRODUCT\10.2.0\ADMIN\ORCL\UDUMP\orcl_ora_5928.trc

? ? ? 弹出一个output = 要你输入解析日志之后的文件存放的目录,可以填写c:\tk.prof ,必须prof后缀。

? ? ? 这个时候我们可以用记事本打开tk.prof文件查看上述两条查询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           0Execute      1      0.00       0.00          0          0          0           0Fetch        2      0.00       0.00          0         34          0           1------- ------  -------- ---------- ---------- ---------- ----------  ----------total        4      0.00       0.00          0         34          0           1select * 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           0Execute      1      0.00       0.00          0          0          0           0Fetch        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操作次数,费力不讨好。这是因为查找条件字段没有包含分区表的分区键,导致每一个表分区都要扫描,也就是每一个索引分区都要扫描,还不如全表扫描来得快。

? ? ?如果不创建局部索引,而是建立一个全局索引。效率跟不分区差不多,创建局部分区的sql换成:

?

create index t_idx on t(owner,object_type,object_name) global partition by hash(owner) partitions 16 

? ? 其实,对于OLTP系统,分区对于获取数据没有什么正面影响(基本不能提高查询速度)。相反,我们还有非常小心避免产生负面影响,比如上面那个例子。但是对于高度并发修改的环境,分区则可能提供显著的效果,因为分区避免了数据的冲突,你修改这个分区,他修改那个分区,大大降低了发生冲突的可能性。因此,不要盲目使用分区,分区不一定能够提高性能。

?

热点排行