Sql优化(三) 关于oracle的并发
Oracle的并发技术可以将一个大任务分解为多个小任务由多个进程共同完成。合理地使用并发可以充分利用系统资源,提高效率。
一、 并发的种类
Parallel query
Parallel DML(PDML)
Parallel DDL 
Parallel recovery
[@more@]
二、 适用场合
适用parallel的两个条件
  1)大的任务,如全表扫描大表
这和日常生活中的经验是一样的,小任务自己完成都比派发任务省事
  2)系统有足够的资源(cpu/io)
换句话说,并发是在系统资源充足、用户少的系统上,为了充分利用系统资源以提高任务处理速度而设计的一种技术。以下是几种场景:
  1)OLTP系统 有大量用户和session,如果每个session使用并发查询将导致系统崩溃。但也有例外例如计费系统月底或下班后没有或用户很少访问,运行批处理程序,此时可使用并发提高速度
  2)数据仓库系统 通常可使用并发查询、PDML等并发,注意有些数据仓库系统也提供给大量用户访问,这种系统有某些OLTP特性,应慎用并发
  3)无论是OLTP还是数据仓库,维护期间使用parallel ddl和PDML对管理员来说是非常有用的
三、 Parallel query
使用并发查询的方法:
  1)修改表属性
Alter table big_table parallel 4;
Alter
 table big_table parallel
;由oracle根据系统资源情况决定。这是推荐的.Oracle根据cpu数目乘以parallel threads per
cpu参数(default 2),例如4cpu的机器,oracle决定parallel数目为8
  2)使用hint , select * /*+ PARALLEL(emp,12) */ …
四、 PDML
例子:
ALTER TABLE emp PARALLEL (10);
ALTER SESSION ENABLE PARALLEL DML;
INSERT INTO emp
SELECT * FROM t_emp;
COMMIT;
ALTER SESSION ENABLE PARALLEL DML;
INSERT /*+ PARALLEL(emp,12) */ INTO emp
SELECT /*+ PARALLEL(t_emp,12) */ * FROM t_emp;
COMMIT;
注意:使用parallel后,insert select * 语句自动就使用direct-load了,此时不再需要使用append hint( /*+APPEND */)
PDML的限制:
  不支持有trigger的表,在上面做PDML,能成功,但忽略了并发性
  不支持某些约束,例如self-referential integrity。原因是PDML分为多个独立的session去修改数据,无法保证某些完整性;容易引起死锁已经其他锁问题
  一个session使用了PDML,在commit/rollback之前,另一个session无法再使用PDML
  Advanced replication不支持(因为使用了trigger)
  Deferred constraints(约束的deferred模式指修改操作在提交时才去验证是否满足约束条件)不支持
  分布式事务不支持
  Clustered tables不支持
当违反这些限制,PDML要么报错,要么忽略并行度
五、 并发与空间浪费
  Parallel DDL以及某些PDML依赖于direct path load,即绕过databuffer直接写数据文件。
例如,create table as select ,insert /*+APPEND */,
这
会形成空间浪费,例如倒入1010M数据,每个extent 100m,direct path load会新分配100m
的extent来存放数据(如果有小于100m的extent,常规insert可以用这些空间)。假设10个并发,每个并发倒入101M数据,会创建2
个extent,则总共会创建20个extent,则形成990m空间浪费。一方面浪费了空间(如果表创建之后有常规insert,则能使用这些空间),
另一方面全表扫描时会搜索这些空的extent,这也降低了全表扫描的速度。
表空间的extent管理有两种方式,unform size,则每个extent大小相同,autoallocate是oracle根据内部机制决定extent大小,更灵活
Uniform 方式不支持extent trimming,而autoallocate在parallel ddl中用到extent trimming,减少了空间浪费。
因此在频繁使用parallel DDL操作的表空间上,要么减少uniform size每个extent的大小,要么使用autoallocate ,以减少空间浪费。
六、 并发DIY-存储过程的并发
以下是一个常见任务:扫描全表,修改数据,再写入新的表
如果一个进程处理太慢,我们通常会自己将数据划分,然后开多个进程调用。
使用11gr2 内置的并发包:DBMS_PARALLLEL_EXECUTE,大大简化了这一过程
(11gr2之前,没有内置的并发程序包,需要手工按照rowid或主键划分大表,然后通过dbms_job或dbms_schedule并发调用。)
我们以前两天***的一个程序为例,看看如何使用这一并发技术(本例较简单,不见得需要使用这样技术,仅仅作为例子来说明)
程序的目的是删除bmf中orig_bill_ref_no like '18%'的记录,本来一句sql可以完成,由于数据量太大,系统回滚段不足。因此开发人员准备分多个进程运行
declare 
cursor c1 
is select orig_bill_ref_no from bmf where orig_bill_ref_no like '18%' 
and mod(account_no, 5) = 0; (将数据分为5段)
begin 
  for r1 in c1 loop 
  delete from bmf where orig_bill_ref_no = r1.orig_bill_ref_no; 
  commit; 
  end loop;
  commit; 
end; 
/
这
样的写法会有什么问题呢,很快就遇到snapshot too
old错误了。原因是select打开bmf游标,同时修改bmf并commit数据,由于查询一致性要求,打开的游标要看到的是bmf修改之前的情况,
这是从undo去读的,因此一旦时间超出undo_retention,undo信息过期,就报snapshot too old了。
使用ora11g提供的并发包的写法:
1) 创建过程serial过程,用来被多个并发线程调用
create or replace
procedure serial( p_lo_rid in rowid, p_hi_rid in rowid )
 is
 begin
  delete from bmf 
  where rowid between p_lo_rid  and p_hi_rid and orig_bill_ref_no like '15%';
 end;
/
2) 按照rowid将表划分为多个chunk,供线程调用
begin
dbms_parallel_execute.create_task('PROCESS BIG TABLE');
dbms_parallel_execute.create_chunks_by_rowid
( task_name => 'PROCESS BIG TABLE',
table_owner => 'LUW',
table_name => 'BMF',
by_row => false,  --不按行记录数而按block数
chunk_size => 2000 );
end;
 /
select *
 from (
 select chunk_id, status, start_rowid, end_rowid
 from dba_parallel_execute_chunks
 where task_name = 'PROCESS BIG TABLE'
 order by chunk_id
 )
 where rownum <= 5
 /
3) 发起并发任务,按照第2步对表的划分来分配并运行任务
begin
 dbms_parallel_execute.run_task
 ( task_name => 'PROCESS BIG TABLE',
 sql_stmt => 'begin serial( :start_id, :end_id ); end;',
 language_flag => DBMS_SQL.NATIVE,
 parallel_level => 4 );
 end;
 /
4) 删除并发作业                                                              
begin                                                           
 dbms_parallel_execute.drop_task('process big table' );         
 end;                                                           
 /
那么使用并发和简单的delete相比,速度怎样呢
使用并发:
PL/SQL procedure successfully completed.
Elapsed: 00:00:03.07
直接delete:
delete from bmf where orig_bill_ref_no like '15%';
403525 rows deleted.
Elapsed: 00:00:08.12
这说明使用并发提高了速度,更别说对回滚段的空间要求也少了。
Sql优化(三) 关于oracle的并发的更多相关文章
- 基于Oracle的SQL优化(社区万众期待 数据库优化扛鼎巨著)
		
基于Oracle的SQL优化(社区万众期待数据库优化扛鼎巨著) 崔华 编 ISBN 978-7-121-21758-6 2014年1月出版 定价:128.00元 856页 16开 编辑推荐 本土O ...
 - oracle sql优化笔记
		
oracle优化一般分为:1.sql优化(现在oracle都会根据sql语句先进行必要的优化处理,这种应该用户不大了,但是像关联和嵌套查询肯定是和影响性能的) A.oracle的sql语句的条件是从右 ...
 - 大型系统开发sql优化总结(转)
		
Problem Description: 1.每个表的结构及主键索引情况 2.每个表的count(*)记录是多少 3.对于创建索引的列,索引的类型是什么?count(distinct indexcol ...
 - oracle性能优化(项目中的一个sql优化的简单记录)
		
在项目中,写的sql主要以查询为主,但是数据量一大,就会突出sql性能优化的重要性.其实在数据量2000W以内,可以考虑索引,但超过2000W了,就要考虑分库分表这些了.本文主要记录在实际项目中,一个 ...
 - ORACLE常用SQL优化hint语句
		
在SQL语句优化过程中,我们经常会用到hint,现总结一下在SQL优化过程中常见Oracle HINT的用法: 1. /*+ALL_ROWS*/ 表明对语句块选择基于开销的优化方法,并获得最佳吞吐量, ...
 - oracle sql优化
		
整理一下网上所看到sql优化方法 1.使用大写字母书写sql,因为oracle解释器会先将sql语句转换成大写后再解释 2 减少访问数据库的次数,多数情况下一条sql可以达到目的的,就不要使用多 ...
 - 读书笔记-《基于Oracle的SQL优化》-第一章-3
		
优化器: 1.优化器的模式: 用于决定在Oracle中解析目标SQL时所用优化器的类型,以及决定当使用CBO时计算成本值的侧重点.这里的“侧重点”是指当使用CBO来计算目标SQL各条执行路径的成本值时 ...
 - sql优化(oracle)
		
系统优化中很重要的方面是SQL语句的优化,对于海量数据,优质的SQL能够有效的提高系统的可用性. 总结的有点罗嗦,列个简单的目录啦~ 目录 第一部分知识准备 ...
 - SQL优化(Oracle)
		
(转)SQL优化原则 一.问题的提出 在应用系统开发初期.因为开发数据库数据比較少.对于查询SQL语句,复杂视图的的编写等体会不出SQL语句各种写法的性能优劣,可是假设将应用系统提交实际应用后,随着数 ...
 
随机推荐
- Java中创建对象的5种方式  &&new关键字和newInstance()方法的区别
			
转载:http://www.kuqin.com/shuoit/20160719/352659.html 用最简单的描述来区分new关键字和newInstance()方法的区别:newInstance: ...
 - python 多线程爬虫
			
最近,一直在做网络爬虫相关的东西. 看了一下开源C++写的larbin爬虫,仔细阅读了里面的设计思想和一些关键技术的实现. 1.larbin的URL去重用的很高效的bloom filter算法: 2. ...
 - Lazarus中TreeView导出XML以及XML导入TreeView
			
本来说是要给自己的某程序加一个xml导出功能,但是自己也没接触过xml,加之delphi和lazarus的xml部分还都不一样,折腾好久(整一天)才解决问题.. 如下是作为导出功能的组件部分: uni ...
 - js查找元素
			
1.className <!DOCTYPE html> <html> <head lang="en"> <meta charset=&qu ...
 - jacob 操作word转pdf
			
项目需要对上传的word及pdf进行在线预览,因基于jquery的pdf插件,很方面实现在线预览,而word实现在线预览费劲不少,于是想到在进行上传处理时,直接将word转成pdf,在预览时直接预览p ...
 - 一维树状数组(HD1166)
			
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<string.h> using namespace st ...
 - 转载:10 Easy Steps to a Complete Understanding of SQL
			
10 Easy Steps to a Complete Understanding of SQL 原文地址:http://tech.pro/tutorial/1555/10-easy-steps-to ...
 - 使用Mindjet MindManager 制作流程图案例
			
心得体会是: 导出为swf格式的流程图最为美观 有些过于复杂的对象在swf viewer中是无法显示的(比如各种表格,任务,提醒,自定义属性). 所有主题和子主题在viewer刚打开的时候一定都是全部 ...
 - 为Delphi程序增加UAC功能
			
相关资料:http://bbs.csdn.net/topics/320071356# 操作方法: 在Source\VCL目录下应该有这样两个文件sample.manifest和WindowsXP.rc ...
 - Android Studio优化之启用Shift+Ctrl+O导入所有的包
			
在使用Eclipse开发Android应用时,开发者往往会使用Shift+Ctrl+O快捷键来快速导入所有的包,和移除已经导入但还未使用的包.但这个快捷键在Android Studio没人是给有开启的 ...