oracle海量数据中提升创建索引的速度

基本信息情况:

数据库版本:Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production

操作系统版本:CentOS release 5.6

加快创建索引速度主要从一下角度考虑:

  • 使用nologging 参数
  • 使用parallel 并行参数
  • 在session级别使用manual pga,手动调整sort_area_size
  • 修改其他参数

注意:我们这里不手动调整hash_area_size,hash_area_size 默认情况下会自动根据sort_area_size*2来调,导致sort_area_size不能超过1G。所以我们这里直接调整sort_area_size参数。

 

这里首先记录pga使用的情况,9i以后查询pga分配和使用可以查询v$pgastat视图。

[sql] view plaincopy

  1. SQL> desc v$pgastat;
  2. 名称
  3. --------------------------------
  4. NAME 名称
  5. VALUE 值
  6. UNIT 单位
  7. -------------------统计项
  8. select * from v$pgastat
  9. NAME                                          VALUE UNIT
  10. ---------------------------------------- ---------- ----------
  11. aggregate PGA target parameter            150994944 bytes
  12. aggregate PGA auto target                  93579264 bytes
  13. global memory bound                        30198784 bytes
  14. total PGA inuse                            47017984 bytes
  15. total PGA allocated                        56666112 bytes
  16. maximum PGA allocated                      58632192 bytes
  17. total freeable PGA memory                   2883584 bytes
  18. process count                                    23
  19. max processes count                              48
  20. PGA memory freed back to OS                 5177344 bytes
  21. total PGA used for auto workareas                 0 bytes
  22. maximum PGA used for auto workareas               0 bytes
  23. total PGA used for manual workareas               0 bytes
  24. maximum PGA used for manual workareas             0 bytes
  25. over allocation count                             0
  26. bytes processed                             6438912 bytes
  27. extra bytes read/written                          0 bytes
  28. cache hit percentage                            100 percent
  29. recompute count (total)                         123

 

对于上面的解释如下

1 aggregate PGA target parameter 150994944 bytes : pga_aggregate_target
2 aggregate PGA auto target 93579264 bytes : 剩余的能被工作区使用的内存。
3 global memory bound 30198784 bytes :单个SQL最大能用到的内存
4 total PGA inuse 47017984 bytes :正被耗用的pga(包括workare pl/sql等所有占用的pga)
5 total PGA allocated 56666112 bytes :当前实例已分配的PGA内存总量。
一般来说,这个值应该小于 PGA_AGGREGATE_TARGET ,
但是如果进程需求的PGA快速增长,它可以在超过PGA_AGGREGATE_TARGET的限定值
6 maximum PGA allocated 58632192 bytes :pga曾经扩张到的最大值
7 total freeable PGA memory 2883584 bytes :可释放的pga
8 process count 23 :当前process
9 max processes count 48 :最大时候的process
10 PGA memory freed back to OS 5177344 bytes
11 total PGA used for auto workareas 0 bytes :当前auto模式下占用的workara size 大小
12 maximum PGA used for auto workareas 0 bytes :auto模式下占用的workara size最大 大小
13 total PGA used for manual workareas 0 bytes :当前manual模式下占用的workara size 大小
14 maximum PGA used for manual workareas 0 bytes :manual模式下占用的workara size最大 大小
15 over allocation count 0 :使用量超过pga大小的次数
16 bytes processed 6438912 bytes :pga使用的字节
17 extra bytes read/written 0 bytes :向临时段写的字节
18 cache hit percentage 100 percent :bytes processed/(bytes processed+extra bytes read/written)
19 recompute count (total) 123

global memory bound:一个串行操作能用到的最大内存
=min(5%*pga_aggregate_target,50%*_pga_max_size,_smm_max_size),
当你修改参数pga_aggregate_target的值时,Oracle系统会根据pga_aggregate_target和_pga_max_size
这两个值来自动修改参数_smm_max_size。具体修改的规则是:
如果_pga_max_size大于5%*pga_aggregate_target,则_smm_max_size为5%*pga_aggregate_target。
如果_pga_max_size小于等于5%*pga_aggregate_target,则_smm_max_size为50%*_pga_max_size。

total PGA in used:当前正在使用的PGA,可以从v$process的pga_used_mem字段中获取
select sum(a.PGA_USED_MEM),sum(a.PGA_ALLOC_MEM),sum(a.PGA_MAX_MEM) from v$process a
v$pgastat 中的 total PGA in used、total PGA allocated、maximum PGA allocated
这3个值差不多

在执行创建索引前,我们还要介绍一个视图v$session_longops视图

[sql] view plaincopy

  1. SQL> desc v$session_longops
  2. 名称 是否为空? 类型
  3. ----------------------------------------- -------- ----------------
  4. SID NUMBER
  5. SERIAL# NUMBER
  6. OPNAME VARCHAR2(64)
  7. TARGET VARCHAR2(64)
  8. TARGET_DESC VARCHAR2(32)
  9. SOFAR NUMBER
  10. TOTALWORK NUMBER
  11. UNITS VARCHAR2(32)
  12. START_TIME DATE
  13. LAST_UPDATE_TIME DATE
  14. TIME_REMAINING NUMBER
  15. ELAPSED_SECONDS NUMBER
  16. CONTEXT NUMBER
  17. MESSAGE VARCHAR2(512)
  18. USERNAME VARCHAR2(30)
  19. SQL_ADDRESS RAW(4)
  20. SQL_HASH_VALUE NUMBER
  21. QCSID NUMBER

其中SID和SERIAL#是与v$session中的匹配的,
OPNAME:指长时间执行的操作名.如:Table Scan
TARGET:被操作的object_name. 如:tableA
TARGET_DESC:描述target的内容
SOFAR:这个是需要着重去关注的,表示已要完成的工作数,如扫描了多少个块。
TOTALWORK:指目标对象一共有多少数量(预计)。如块的数量。
UNITS:
START_TIME:进程的开始时间
LAST_UPDATE_TIM:最后一次调用set_session_longops的时间
TIME_REMAINING: 估计还需要多少时间完成,单位为秒
ELAPSED_SECONDS:指从开始操作时间到最后更新时间
CONTEXT:
MESSAGE:对于操作的完整描述,包括进度和操作内容。
USERNAME:与v$session中的一样。
SQL_ADDRESS:关联v$sql
SQL_HASH_VALUE:关联v$sql
QCSID:主要是并行查询一起使用。

下面测试正式开始

1、使用python脚本创建随机数

import random

‘‘‘

Created on 2012-3-26

@author: jscn-xw

‘‘‘

for j in range(1,10):

for i in range(1,10000000):

print random.randint(100000000,999999999),random.randint(100000000,999999999)

2、创建测试表

SQL> create table tbim(id1 number,id2varchar2(12)) nologging;

3、load进入数据

3.1 创建控制文件(tbim.ctl)

load data

--infile ‘/home/oracle/bi_logfile.txt‘

into table tbim

append

fields terminated by ‘ ‘

OPTIONALLY ENCLOSED BY ‘"‘

trailing nullcols

(

id1       ,

id2

)

3.2 sqlldr进入数据库

[[email protected]]$ sqlldr userid=security/security control=tbim.ctldata=/home/oracle/tbim.bcp

4 测试

SQL> set timing on

SQL> select count(*) from tbim ;

COUNT(*)

----------

400000000

Elapsed: 00:00:06.57

4.1 什么参数都不加测试创建速度

SQL> create index id1_ind on tbim(id1) tablespace imindex;

Index created.

Elapsed: 00:16:23.51

这个时候注意观察临时表空间的变化情况,我们注意临时表空间在不断的增加。还要注意v$session_longops视图的变化。

主要关注SOFAR、TIME_REMAINING、ELAPSED_SECONDS字段的变化和值

4.2 加上nologing参数

SQL> drop index id1_ind;

SQL> create index id1_ind on tbim(id1)tablespace imindex nologging;

Index created.

Elapsed: 00:16:40.20

4.3 加上parallel参数

SQL> drop index id1_ind;

SQL> create index id1_ind on tbim(id1)tablespace imindex nologging parallel 4;

Index created.

Elapsed: 00:09:03.74

感觉parallel不靠谱,而且nologging效果也不是很明显,至少对于oracle11gR2来说。

4.4 调整sort_area_size

SQL> alter session setworkarea_size_policy=manual;

SQL> alter session setworkarea_size_policy=manual;

SQL> alter session setsort_area_size=2000000000;

SQL> alter session setsort_area_size=2000000000;

SQL> create index id1_ind on tbim(id1)tablespace imindex nologging parallel 4;

Index created.

Elapsed: 00:08:12.79

这个效果还是比较明显的

4.5 修改其他参数

修改全表扫描时一次读取的block的数量db_file_multiblock_read_count

直接路径IO的大小,10351 event level 128

禁用block checksum/checking

备选的排序算法_newsort_type

SQL> alter session setdb_file_multiblock_read_count=1024;

SQL> alter session setdb_file_multiblock_read_count=1024;

SQL> alter session set events ‘10351trace name context forever, level 128‘;

SQL> alter session setsort_area_size=2000000000;

SQL> alter session setsort_area_size=2000000000;

SQL> alter session set"_sort_multiblock_read_count"=128;

SQL> alter session set"_sort_multiblock_read_count"=128;

SQL> alter session enable parallel ddl;

SQL> alter session setdb_block_checking=false;

SQL> alter system setdb_block_checksum=false;

SQL> create index id1_ind on tbim(id1)tablespace imindex nologging parallel 4;

Index created.

Elapsed: 00:07:37.57

5、总结

我可以通过以下手段加快创建索引速度:

1)除此之外,还可以适当的调整并行查询的数量(一般不超过8);

2)索引和表分离,单独的临时表表空间;

3)把表调整为nologging状态,或者创建索引的时候指定nologging;

4)我们可以适当调整数据库相关参数加快左右创建索引速度,示例如下:

SQL> alter session setdb_file_multiblock_read_count=1024;

SQL> alter session setdb_file_multiblock_read_count=1024;

SQL> alter session set events ‘10351trace name context forever, level 128‘;

SQL> alter session setsort_area_size=2000000000;

SQL> alter session setsort_area_size=2000000000;

SQL> alter session set"_sort_multiblock_read_count"=128;

SQL> alter session set "_sort_multiblock_read_count"=128;

SQL> alter session enable parallel ddl;

SQL> alter session setdb_block_checking=false;

SQL> alter system setdb_block_checksum=false;

通过以上调整一般可以加快40%以上的创建速度

时间: 2024-10-14 12:53:16

oracle海量数据中提升创建索引的速度的相关文章

oracle 物化视图及创建索引

物化视图是一种特殊的物理表,“物化”(Materialized)视图是相对普通视图而言的.普通视图是虚拟表,应用的局限性大,任何对视图的查询,Oracle都实际上转换为视图SQL语句的查询.这样对整体查询性能的提高,并没有实质上的好处. 1.物化视图的类型:ON DEMAND.ON COMMIT 二者的区别在于刷新方法的不同,ON DEMAND顾名思义,仅在该物化视图“需要”被刷新了,才进行刷新(REFRESH),即更新物化视图,以保证和基表数据的一致性:而ON COMMIT是说,一旦基表有了C

oracle 创建索引思考(转)

在Oracle数据库中,创建索引虽然比较简单.但是要合理的创建索引则比较困难了. 笔者认为,在创建索引时要做到三个适当,即在适当的表上.适当的列上创建适当数量的索引.虽然这可以通过一句话来概括优化的索引的基本准则,但是要做到这 一点的话,需要数据库管理员做出很大的努力.具体的来说,要做到这个三个适当有如下几个要求. 一. 根据表的大小来创建索引. 虽然给表创建索引,可以提高查询的效率.但是数据库管理员需要注意的是,索引也需要一定的开销的.为此并不是说给所有的表都创建索引,那么就 可以提高数据库的

oracle数据库什么情况下创建索引比较好

索引就好象一本字典的目录.凭借字典的目录,我们可以非常迅速的找到我们所需要的条目.数据库也是如此.凭借Oracle数据库的索引,相关语句可以迅速的定位记录的位置,而不必去定位整个表. 虽 然说,在表中是否创建索引,不会影响到Oracle数据库的使用,也不会影响数据库语句的使用.这就好像即使字典没有目录的话,用户仍然可以使用它一 样.可是,若字典没有目录,那么可想而知,用户要查某个条目的话,其不得不翻遍整本字典.数据库也是如此.若没有建立相关索引的话,则数据库在查询记录的 时候,不得不去查询整个表

物化视图,索引视图,函数索引,创建索引时使用DESC

老板交给的一个任务,搜了一下资料,觉得还是总结一下比较好.假如以后用到了呢?围绕两个主题:一是视图上能够建索引,二是在创建索引时是否可以使用DESC关键字. 一.能否在视图上创建索引 因为普通的视图并没有存储实际的信息,它所操作的数据来自于基本表,所以在普通视图上不可以创建索引. 在oracle中执行如下的语句,会报"视图不适用于此处"的错误 create view test_car as select license from cars; create index index_vew

Oracle外键需要建索引吗?

关于Oracle中的外键,首先要说明一下. 1. 除非已定义了父表主键或唯一键约束,否则oracle将不允许创建子表的外键约束. 2. 在定义外键约束时,oracle不会自动创建索引,所以必须手动在与外键约束相关的列上创建索引. 所以我们这里要研究的是否需要在子表中创建索引,因为父表中对应的列是一定有索引的. 如果子表中的外键不创建索引,将导致两个问题. 1. 影响性能. 如果子表外键没有创建索引,那么当父表查询关联子表时,子表将进行全表扫描. 2. 影响并发. 如果子表外键没有创建索引,那么在

Native Oracle Barcode Generator可以添加条形码到Oracle Reports中而不用安装特定的字体库

Native Oracle Barcode Generator条形码控件是一个可以被嵌入到Oracle Reports中用于创建条码图像的一个对象.一旦安装后,不需要安装其它的任何组件或字体库来创建条码:它是完整的条码生成器. 具体功能: 轻松地添加条形码到Oracle Reports中而不用安装特定的字体库. 包括正在申请专利的技术在其他任何公司都是无法获得的. 在一个编译好的PLL库中提供一个完整的Oracle 条码生成器对象. 创建的本地和纯PL/SQL 代码的源代码是可用的. 多地区设置

【MySQL】MySQL中针对大数据量常用技术_创建索引+缓存配置+分库分表+子查询优化(转载)

原文地址:http://blog.csdn.net/zwan0518/article/details/11972853 目录(?)[-] 一查询优化 1创建索引 2缓存的配置 3slow_query_log分析 4分库分表 5子查询优化 二数据转移 21插入数据 如今随着互联网的发展,数据的量级也是撑指数的增长,从GB到TB到PB.对数据的各种操作也是愈加的困难,传统的关系性数据库已经无法满足快速查询与插入数据的需求.这个时候NoSQL的出现暂时解决了这一危机.它通过降低数据的安全性,减少对事务

oracle 创建索引

适当的使用索引可以提高数据检索速度,可以给经常需要进行查询的字段创建索引. oracle的索引分为5种:唯一索引,组合索引,反向键索引,位图索引,基于函数的索引 创建Oracle索引的标准语法: CREATE INDEX 索引名 ON 表名 (列名) TABLESPACE 表空间名; 创建唯一索引: CREATE unique INDEX 索引名 ON 表名 (列名) TABLESPACE 表空间名; 创建组合索引: CREATE INDEX 索引名 ON 表名 (列1,列2) TABLESPA

Oracle性能分析8:创建索引

在创建索引时,我们往往希望能够预估索引大小,以评估对现有工程环境的影响,我们也希望创建索引的过程能够最小化的影响我们正在运行的工程环境,并能查看索引的状况. 预估索引大小 预估索引大小,最好的办法是在测试环境中创建它,测试环境最好包含完整的工程环境数据,否则只有通过部分数据来推算完整的索引大小. 如果不能搭建测试环境,Oracle提供了存储过程DBMS_SPACE.CREATE_INDEX_COST来估算索引的大小,下面是一个例子: declare used_bytes number(10);