设为首页 收藏本站
查看: 673|回复: 0

[经验分享] oracle海量数据加快创建索引速度

[复制链接]

尚未签到

发表于 2016-7-28 07:14:07 | 显示全部楼层 |阅读模式
  基本信息情况:
  数据库版本: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> desc v$pgastat;名称 --------------------------------NAME 名称 VALUE 值 UNIT 单位 -------------------统计项 select * from v$pgastatNAME                                          VALUE UNIT---------------------------------------- ---------- ----------aggregate PGA target parameter            150994944 bytes aggregate PGA auto target                  93579264 bytesglobal memory bound                        30198784 bytestotal PGA inuse                            47017984 bytestotal PGA allocated                        56666112 bytesmaximum PGA allocated                      58632192 bytestotal freeable PGA memory                   2883584 bytesprocess count                                    23max processes count                              48PGA memory freed back to OS                 5177344 bytestotal PGA used for auto workareas                 0 bytesmaximum PGA used for auto workareas               0 bytestotal PGA used for manual workareas               0 bytesmaximum PGA used for manual workareas             0 bytesover allocation count                             0bytes processed                             6438912 bytesextra bytes read/written                          0 bytescache hit percentage                            100 percentrecompute 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> desc v$session_longops名称 是否为空? 类型----------------------------------------- -------- ----------------SID NUMBERSERIAL# NUMBEROPNAME VARCHAR2(64)TARGET VARCHAR2(64)TARGET_DESC VARCHAR2(32)SOFAR NUMBERTOTALWORK NUMBERUNITS VARCHAR2(32)START_TIME DATELAST_UPDATE_TIME DATETIME_REMAINING NUMBERELAPSED_SECONDS NUMBERCONTEXT NUMBERMESSAGE VARCHAR2(512)USERNAME VARCHAR2(30)SQL_ADDRESS RAW(4)SQL_HASH_VALUE NUMBERQCSID 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进入数据库
  [oracle@jscns-05CTL]$ 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%以上的创建速度
  

  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-250325-1-1.html 上篇帖子: Oracle 10G windows 平台 DataGuard 实例(三) 下篇帖子: oracle简单学习总结(三)——函数
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表