首页 > 数据库 > Oracle > 并行直接加载和系统调整的一点思路
并行执行一个在OLAP系统经常出现的技术,这个可以简单描述的是处理一个sql语句时,任务被并行协调进程划分为多个并行处理单元,然后交给相应的并行服务进程,而后并行协调进程又分配其他 的并行处理单元,直到处理完所有的单元都完成,最后协调进程把所有的并行服务处理的单位合并起为一个集合交互给客户端。
为什么说多用于OLAP系统了,因为OLTP系统大多都是高效的索引读取,而高效的索引读取
完全没有必要开启并行。而并行利用多个cpu单位来共享完成任务,更多用于cpu空闲的系统,
由于OLAP系统中并发较少,cpu相对比较空闲,大多是相对于报表的功能的sql,此时sql层面上很难优化,开启并行是可以大幅提升sql的执行。
这里说一下对磁盘的性能的分析,对于OLTP系统大多是索引读取,每次IO大多单块IO,对于OLTP系统更看重磁盘的IOPS,也就是每秒的IO次数。
而OLAP系统由于大多是聚集函数报表功能,每次IO多大是fts的多块读取,更看重磁盘的每次IO读取的容量,也就是最大吞吐量mbps。
这里介绍一个并行执行可以查看并行度的视图v$px_process
首先在session A上执行:
select /*+parallel(inf_apply_process)*/* from jhqlnwhxdb.inf_apply_process;
而后在session b上查看开启的并行执行进程:
SQL> select pid,server_name from
v$px_process;
PID SERVER_NAME
---------- -----------
743 P006
744 P007
750 P013
738 P001
741 P004
740 P003
748 P011
745 P008
746 P009
742 P005
752 P015
737 P000
739 P002
749 P012
747 P010
751 P014
16 rows selected
SQL> show parameter cpu;
NAME TYPE VALUE
------------------------------------ -----------
cpu_count
integer 8
parallel_threads_per_cpu
integer 2
SQL>
show parameter parallel_adaptive_multi_user;
NAME TYPE VALUE
------------------------------------
----------- ------------------------------
parallel_adaptive_multi_user boolean TRUE
parallel_adaptive_multi_user参数表示oracle会自动对并行度进行动态调整。还有几个有关并行的参数parallel_min_server是oracle数据库启动预先分配的并行进程,parallel_max_server是oracle允许分配的最大进程数。
默认的并行度优先级是hint>alter session
force>table级别,有一点需要注意的是:
select
/*+parallel(a 2)*/count(*),host from zebra.robots_article a group by host;如果hint并行,可以查看这个sql语句有两个步奏,一个是全表扫描的robots_article,还有一个group by hash的聚集,所以需要分配并行服务进程子进程和并行服务的父进程。有时候发现并行服务进程是并行度的二倍时就是并行服务的父进程的原因。
PX Deq
Credit :send blkd并行等待事件这个是经常出现于并行执行中,这个是由于并行执行时多个并行服务进程传递结果集给并行协调进程导致,由于并行协调进程同一时刻只能接受一个并行服务进程发送的结果集,此时就可能会产生所谓的等待。当系统因为此并行等待事件引起系统瓶颈时,可以采取降低并行度来减少此等待事件引起的系统压力。
经常听见各种帖子 书籍上面都写到在资源充足时是可以利用parallel来提高sql语句的性能的,充足如何去判断确是一个值得斟酌的,并行度如何去设定同样也是一个值得斟酌的,当然需要先去os上定位系统负载例如top vmstat iostat sar等强大的命令都可以对系统的负载有个简单的了解,相信对os上如何诊断资源情况对于何时开启并行还是有个比较清晰的认识的。
那么如何设置并行度了,个人一般都是在sql语句中让oracle自己去选择并行度,当然也可以根据系统负载和cpu process等信息手动设置,总是预想的是采取分解任务的思想用资源去换取时间。
直接加载append是直接把数据加载到高水位线之上,减少寻找数据块的时间,append的nologging方式下可以减少redo的产生的,实际上由于nologging模式下,append插入redo不会记录数据块的修改,同样由于是append的插入直接在HWM之上,而HWM之上的数据块是无法查看的,也不需要对修改的数据块维护undo,如果rollback此时仅仅只需要维护HWM不变即可。(不过logging方式的append插入是否需要维护undo了),此时产生的undo和redo仅仅只是维护数据字典 空间分配等。效率自然比平常的插入效率要高,不过由于不写redo,这部分数据并不记录在archivelog中。
记得有很多帖子说到如何高效插入大批量数据, 加载数据的方法很多,exp/imp expdp/impdp sql语句 sqlldr等的,不过就其基本可以采用如下并行 nologging 直接加载 禁掉索引方式插入,直接高水位或者绕过缓存,nologging不写入redo,禁掉索引较少索引的维护和期间产生的redo和undo等信息,并行利用资源换取空间。
谈谈对于系统调优的一点想法:对于调优其实更应该说是调整,对于系统来说,数据库层面上的调整的收效往往是最低的,而应用的设计和需求,schemas的设计往往是最能最大程序提高系统性能的,结合合理的硬件,而dba要做的最多的应该是数据库的备份和恢复,配合开发设计合理的应用和方案,后面的系统上线数据量起来后相对来说调整得很少,因为sql已经写好了,代码和业务逻辑已经全部实现,此时大幅度修改业务逻辑和代码基本来说是不可能的,曾几何时也想着数据库调优总是可以解决n多系统瓶颈,第一次看TOM的9i-10g编程艺术时对于数据库也就能提高系统10%左右的性能感到非常的不理解,随着慢慢接触的越来越多,结合很多实例发觉这句活绝对的合理。
举个简单的例子:需求实时统计大表的数据量,也就是一个select count(*) from a也就是只要有人进入某个系统的模块就能查看相应的a表总的数据量,如果a表的数据量特别大,实时统计对于系统的压力可想而知,大表的fts对于磁盘的IO绝对是个考验,而如果是并发较大多个session同时执行,相信系统的负载基本是不用做别的事情了,就是等待等待,这个如果从需求层次上来说,可以一天统计一次a表的数量到临时表b中,而让用户每次直接查询select * from b即可,在业务不繁忙时对a表进行查询写进b表,这个对于系统来说跟前面相比简直是区别太大了,合理的需求和设计很是重要的。
接下来就是schemas的设计,由于自己不是做数据架构的方面的,对于数据库的schemas设计也不是很清晰,但是这个阶段可以说也是非常重要的,把业务逻辑如何实现在各个对象上,往往也是提高系统性能的最直接的方法,而不要到最好各种IO等待,热点块,gc的同步产生的热点快,enq并发请求等数据库等待事件,此时dba又不得不硬着头皮上了,物化视图 sql调整,index的创建方式 hint写法等,此时不得不把最后dba系统维护的阶段的工作提前做了,其实往往取得效果并不明显或者不容易取得。
啰唆了半天,数据库是一个需要循序渐进的过程,有些话当时不理解可能到合适的时候就会忽然开朗,这里推荐一本谭大师写的书<<让oracle跑得更快>>,个人觉得还是写得很不错的,适合有一定基础的oracle爱好者反复翻看体会作者的思想。
[@more@]
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/25362835/viewspace-1059045/ ,如需转载,请注明出处,否则将追究法律责任。