system: [SYSTEM]

user: 4. 系统优化 4.1. 并行和OLAP系统 4.1.1. 并行处理机制 并行技术是OLAP系统的一个非常重要的技术，这种数据并行处理方式在0LAP系统非常有用，OLAP系统的表通常来说都非常大，如果系统的CPU比较多的话，让所有的CPU一起共同来处理这些数据，效果就会比串行执行要高的多；然而对于OLTP系统，通常来讲，并行并不合适，原因是OLTP系统上几乎在所有的SQL操作中，数据访问路径基本上以索引访问为主，并且返回结果集非常小，这样的SQL操作的处理速度一般非常快，此时不需要启用并行。 4.1.2. 并行执行的适用范围以及SQL并行优化实例 Oracle的并行技术在下面的场景中都可以使用：Parallel Query(并行查询)、Parallel DDL(并行DDL操作，比如建表，建索引等)、Parallel DML(并行DML操作，比如INSERT， UPDATE， DELETE等)。 对于气象及污染数据仓库系统中的查询操作，可以使用并行技术优化查询语句速度。通过E_BUL_DAY(编报日)进行分组，以E_RECEIVE_TIME(公报入库时间)进行排序，查询常规天气公报数据，这种分组排序SQL是典型的OLAP系统的SQL，其SQL语句如下所示： select E_MARK， E_ENTER_TIME，E_RECEIVE_TIME，E_BUL_CENTER，E_BUL_YEAR，E_BUL_MONTH， E_BUL_DAY，E_BUL_HM，E_BUL_CATEGORY，E_CEOCODE，E_BUL_NUMBER，E_BUL_COR_MARK，E_BUL_LEN，E_BULLETIN from OBS_WEA_BUL_ENT group by E_BUL_DAY order by E_RECEIVE_TIME desc; 然而一个查询能够并行执行，需要满足以下条件： 1) SQL语句中有Hint提示，比如PARALLEL或者PARALLEL_INDEX。 2) SQL语句中引用的对象被设置了并行属性。 3) 多表关联中，至少有一个表执行全表扫描(FULLTABLESCAN)或者跨越分区的INDEXRANGE SACN。 本系统中应用的方法是Hint的方式，修改后的SQL如下所示： select/*+parallel(OBS_WEA_BUL_ENT4)*/E_MARK，E_ENTER_TIME，E_RECEIVE_TIME，E_BUL_C ENTER，E_BUL_YEAR，E_BUL_MONTH，E_BUL_DAY，E_BUL_HM，E_BUL_CATEGORY，E_CEOCODE，E_BUL_NUMBER，E_BUL_COR_MARK，E_BUL_LEN，E_BULLETIN from OBS_WEA_BUL_ENT group by E_BUL_DAY order by E_RECEIVE_TIME desc; 上面的SQL语句通过加上Hint提示，即加上/*+parallel(OBS_WEA_BUL_ENT4)*/便可以利用多个CPU进行并行查询，提高查询速度，本例中并行度为4，即利用4个并行服务进程进行数据扫描(子进程)，另外4个并行服务进程负责数据的排序(父进程)，他们同时工作，子进程实时将扫描到的数据块传递给父进程，父进程同时将数据排序；父进程按照字段E_RECEIVE_TIME的列值将结果集分成了四个部分，这样每个子进程将相应的数据传到对应的父进程上，所以每个子进程都可能会和所有的父进程有数据传递，最后父进程将所有的排序数据传递给并行服务协调进程，由它将最终的结果返给用户。 需要注意的是并行查询不可以使用在一个远程引用的对象上(比如使用DBLINK访问的对象)。 4.2. 直接加载 Oracle提供两种类型的插入语句：常规插入(conventional insert)和直接路径插入(direct-path insert)，直接路径插入的目的是为了高效地加载大量的数据，它以牺牲部分功能为代价，因此受到很多的限制。直接路径加载把数据直接插入到要修改的段的高水位(HWM)以上，从而生成了最少量的undo(只生成数据字典的undo，不生成块中数据的undo)，且不通过高速缓存，因此它的性能比常规插入要好。如果性能是首要目标，还可以考虑配合使用最小日志模式(nologging)。 直接路径加载的限制： 1) 一张表同时只能有一个直接路径插入，因此不适合小数据量的插入，只适合大批量的数据加载； 2) 在HWM下的空闲空间不会被利用； 3) 一张表在做直接路径插入的同时，同一会话不能对其做任何操作(select都不可以)； 4) 只有insert into …… select ……语句、merge语句和使用OCI直接路径接口的应用程序才可以使用。 根据直接加载的优缺点，决定将直接加载应用在数据迁移中，主要涉及中间临时表到业务表的转换。还是以从SURF_WEA_ELE_TMP(常规地面要素资料临时表)中抽调数据到SURF_WEA_ELE_ENT(常规地面要素资料表)为例，在并行的基础上增加直接加载的Hint，SQL又变为如下形式： insert/* + append parallel(SURF_WEA_ELE_ENT 4)*/into SURF_WEA_ELE_ENT select/* + parallel(SURF_WEA_ELE_TMP) */* from SURF_WEA_ELE_TMP; 直接加载和并行执行一起使用时，Oralce会按照并行度启动相应数量的并行服务进程，像串行执行的直接加载的方式一样，每个并行服务进程都单独分配额外的空间用于加载数据(实际上Oracle为每个并行服务程序分配了一个临时段)，每个并行服务进程将数据首先加载到各自的临时段上，当所有的并行进程执行完毕后，将各自的数据块合并到一起，放到表的高水位之后，如果事务提交，则将高水位线移到新加载的数据之后，这样数据插入的性能将会大大提升。 4.3. 分区索引 针对于分区表的索引有两种，一种是全局索引(global index)，另一种是本地索引(local index)。全局索引即可以分区，也可以不分区。即可以建range分区，也可以建hash分区，即可建于分区表，又可创建于非分区表上，就是说，全局索引是完全独立的，因此它也需要我们更多的维护操作。GLOBAL索引是全局类型的索引，根据实际情况可以调整分区的类别，而并非按照分区结构定义来组织，维护代价相对较高一些，在OLTP环境用得相对较多。 本地索引其分区形式与表的分区完全相同，依赖列相同，存储属性也相同。对于本地索引，其索引分区的维护自动进行，就是说你add、drop、split、truncate表的分区时，本地索引会自动维护其索引分区。一般使用LOCAL索引较为方便，而且维护代价较低，并且LOCAL索引是在分区的基础上去创建索引，类似于在一个子表内部去创建索引，这样开销主要是在分区上，可以很规范的管理起来，在OLAP系统中应用很广泛。 鉴于本地索引对于数据仓库系统的契合度高，并且使用和维护较为方便，所以本系统采用的分区索引是本地索引。依然以常规地面要素资料为范例资料，给出创建SURF_WEA_ELE_ENT(常规地面要素资料实体)表的本地分区索引的部分SQL语句。 create index IDX_SWEE_E_ENTER_TIME on SURF_WEA_ELE_ENT(E_ENTER_TIME) local ( partitioni_range_p1 tablespace tbspart01， partition i_range_p2 tablespace tbspart01， partition i_range_p3 tablespace tbspart01， …… partition i_range_p29 tablespace tbspart02， partition i_range_p30 tablespace tbspart02， partition i_range_p31 tablespace tbspart02 ); 由以上SQL可以看出，本地索引的分区完全继承分区表的分区的属性，包括分区类型，分区的范围值即不需指定也不能更改，也就是说本地索引的分区维护完全依赖于其索引所在表，这样维护起来方便快捷。