oracle游标如何优化,oracle游标怎么使用

Oracle 游标

游标能够根据查询条件从数据表中提取一组记录,将其作为一个临时表置于数据缓冲区中,利用指针逐行对记录数据进行操作。

创新互联-专业网站定制、快速模板网站建设、高性价比福州网站开发、企业建站全套包干低至880元,成熟完善的模板库,直接使用。一站式福州网站制作公司更省心,省钱,快速模板网站建设找我们,业务覆盖福州地区。费用合理售后完善,十载实体公司更值得信赖。

Oracle中的游标分为显示游标和隐式游标 。

在执行SQL语句时,Oracle会自动创建隐式游标,该游标是内存中处理该语句的数据缓冲区,存储了执行SQL语句的结果。通过隐式游标属性可获知SQL语句的执行状态信息。

%found:布尔型属性,如果sql语句至少影响到一行数据,值为true,否则为false。

%notfound:布尔型属性,与%found相反。

%rowcount:数字型属性,返回受sql影响的行数。

%isopen:布尔型属性,当游标已经打开时返回true,游标关闭时则为false。

用户可以显式定义游标。使用显式游标处理数据要4个步骤:定义游标、打开游标、提取游标数据和关闭游标。

游标由游标名称和游标对应的select结果集组成。定义游标应该放在pl/sql程序块的声明部分。

语法格式:cursor 游标名称(参数) is 查询语句

打开游标时,游标会将符合条件的记录送入数据缓冲区,并将指针指向第一条记录。

语法格式:open 游标名称(参数);

将游标中的当前行数据赋给指定的变量或记录变量。

语法格式:fetch 游标名称 into 变量名;

游标一旦使用完毕,就应将其关闭,释放与游标相关联的资源。

语法格式:close 游标名称;

declare

cursor c1 is  select sno,cno,grade from sc;

v_sno sc.sno%type;

v_cno sc.cno%type;

v_grade sc.grade%type;

begin

open c1;

loop

  fetch c1 into v_sno,v_cno,v_grade;

  exit when c1%notfound;--紧跟fetch之后

if c1%found then

dbms_output.put_line(to_char(c1%rowcount)||v_cno);

end if;

end loop;

close c1; 

end;

declare

cursor c1 is select sno,cno,grade from sc;

v_sno sc.sno%type;

v_cno sc.cno%type;

v_grade sc.grade%type;

begin

open c1;

fetch c1 into v_sno,v_cno,v_grade;

while c1%found loop

  dbms_output.put_line(v_sno||v_cno||v_grade);

 fetch c1 into v_sno,v_cno,v_grade;

end loop;

close c1; 

end;

第三种:for

declare

cursor c1 is select sno,cno,grade from sc;

begin

for item in c1 loop

dbms_output.put_line(rpad(item.sno,'10',' ')||rpad(item.cno,'10',' ')||rpad(item.grade,'10',' '));

end loop;

end;

Oracle 数据量非常大(上亿)时,使用存储过程中的游标返回分页查询的10条记录非常耗时,请问如何优化?

select * /*+ FIRST_ROWS */ from XXX where XXX

提高SQL语句的响应时间,快速的先返回 n 行。

SELECT /*+ FIRST_ROWS */ * FROM

(

SELECT A.*, ROWNUM RN

FROM (SELECT * FROM TABLE_NAME) A

WHERE ROWNUM = 40

)

WHERE RN = 21

如何进行oracle数据库性能优化

你最好买一本专门讲ORACLE性能优化的书,好好看看\x0d\x0a1、调整数据库服务器的性能\x0d\x0aOracle数据库服务器是整个系统的核心,它的性能高低直接影响整个系统的性能,为了调整Oracle数据库服务器的性能,主要从以下几个方面考虑: \x0d\x0a1.1、调整操作系统以适合Oracle数据库服务器运行\x0d\x0aOracle数据库服务器很大程度上依赖于运行服务器的操作系统,如果操作系统不能提供最好性能,那么无论如何调整,Oracle数据库服务器也无法发挥其应有的性能。 \x0d\x0a1.1.1、为Oracle数据库服务器规划系统资源 \x0d\x0a据已有计算机可用资源, 规划分配给Oracle服务器资源原则是:尽可能使Oracle服务器使用资源最大化,特别在Client/Server中尽量让服务器上所有资源都来运行Oracle服务。 \x0d\x0a1.1.2、调整计算机系统中的内存配置 \x0d\x0a多数操作系统都用虚存来模拟计算机上更大的内存,它实际上是硬盘上的一定的磁盘空间。当实际的内存空间不能满足应用软件的要求时,操作系统就将用这部分的磁盘空间对内存中的信息进行页面替换,这将引起大量的磁盘I/O操作,使整个服务器的性能下降。为了避免过多地使用虚存,应加大计算机的内存。 \x0d\x0a1.1.3、为Oracle数据库服务器设置操作系统进程优先级 \x0d\x0a不要在操作系统中调整Oracle进程的优先级,因为在Oracle数据库系统中,所有的后台和前台数据库服务器进程执行的是同等重要的工作,需要同等的优先级。所以在安装时,让所有的数据库服务器进程都使用缺省的优先级运行。 \x0d\x0a1.2、调整内存分配\x0d\x0aOracle数据库服务器保留3个基本的内存高速缓存,分别对应3种不同类型的数据:库高速缓存,字典高速缓存和缓冲区高速缓存。库高速缓存和字典高速缓存一起构成共享池,共享池再加上缓冲区高速缓存便构成了系统全程区(SGA)。SGA是对数据库数据进行快速访问的一个系统全程区,若SGA本身需要频繁地进行释放、分配,则不能达到快速访问数据的目的,因此应把SGA放在主存中,不要放在虚拟内存中。内存的调整主要是指调整组成SGA的内存结构的大小来提高系统性能,由于Oracle数据库服务器的内存结构需求与应用密切相关,所以内存结构的调整应在磁盘I/O调整之前进行。 \x0d\x0a1.2.1、库缓冲区的调整 \x0d\x0a库缓冲区中包含私用和共享SQL和PL/SQL区,通过比较库缓冲区的命中率决定它的大小。要调整库缓冲区,必须首先了解该库缓冲区的活动情况,库缓冲区的活动统计信息保留在动态性能表v$librarycache数据字典中,可通过查询该表来了解其活动情况,以决定如何调整。 \x0d\x0a \x0d\x0aSelect sum(pins),sum(reloads) from v$librarycache; \x0d\x0a \x0d\x0aPins列给出SQL语句,PL/SQL块及被访问对象定义的总次数;Reloads列给出SQL 和PL/SQL块的隐式分析或对象定义重装载时在库程序缓冲区中发生的错误。如果sum(pins)/sum(reloads) ≈0,则库缓冲区的命中率合适;若sum(pins)/sum(reloads)1, 则需调整初始化参数 shared_pool_size来重新调整分配给共享池的内存量。 \x0d\x0a1.2.2、数据字典缓冲区的调整 \x0d\x0a数据字典缓冲区包含了有关数据库的结构、用户、实体信息。数据字典的命中率,对系统性能影响极大。数据字典缓冲区的使用情况记录在动态性能表v$librarycache中,可通过查询该表来了解其活动情况,以决定如何调整。 \x0d\x0a \x0d\x0aSelect sum(gets),sum(getmisses) from v$rowcache; \x0d\x0a \x0d\x0aGets列是对相应项请求次数的统计;Getmisses 列是引起缓冲区出错的数据的请求次数。对于频繁访问的数据字典缓冲区,sum(getmisses)/sum(gets)10%~15%。若大于此百分数,则应考虑增加数据字典缓冲区的容量,即需调整初始化参数shared_pool_size来重新调整分配给共享池的内存量。 \x0d\x0a1.2.3、缓冲区高速缓存的调整 \x0d\x0a用户进程所存取的所有数据都是经过缓冲区高速缓存来存取,所以该部分的命中率,对性能至关重要。缓冲区高速缓存的使用情况记录在动态性能表v$sysstat中,可通过查询该表来了解其活动情况,以决定如何调整。 \x0d\x0a \x0d\x0aSelect name,value from v$sysstat where name in ('dbblock gets','consistent gets','physical reads'); \x0d\x0a \x0d\x0adbblock gets和consistent gets的值是请求数据缓冲区中读的总次数。physical reads的值是请求数据时引起从盘中读文件的次数。从缓冲区高速缓存中读的可能性的高低称为缓冲区的命中率,计算公式: \x0d\x0a \x0d\x0aHit Ratio=1-(physical reds/(dbblock gets+consistent gets)) \x0d\x0a \x0d\x0a如果Hit Ratio60%~70%,则应增大db_block_buffers的参数值。db_block_buffers可以调整分配给缓冲区高速缓存的内存量,即db_block_buffers可设置分配缓冲区高速缓存的数据块的个数。缓冲区高速缓存的总字节数=db_block_buffers的值*db_block_size的值。db_block_size 的值表示数据块大小的字节数,可查询 v$parameter 表: \x0d\x0a \x0d\x0aselect name,value from v$parameter where name='db_block_size'; \x0d\x0a \x0d\x0a在修改了上述数据库的初始化参数以后,必须先关闭数据库,在重新启动数据库后才能使新的设置起作用。

Oracle游标sql语句代码块的优化

游标操作的优化:

-- 有一个表格,存储的是用户的名字,将 emp 表中所有的用户名转换成小写,再写入这个表格

create table ename_emp(

ename varchar2(50)

);

-- 下面这个游标的操作,需要 43s时间才能完成

declare

begin

for i in (select ename from emp_liebiao) loop

insert into ename_emp values(lower(i.ename));

commit;

end loop;

end;

-- 因为游标是以行为单位进行数据的操作的,所有游标的效率是比较慢的,而且游标需要消耗的内存也是比较多的,我们需要将游标以行进行操作的方式,修改成一次性操作所有数据的批量的方式。

批量操作在游标里面 叫做 bulk collect

第一步,创建一个表类型

type 表类型的名字 is table of 表名.列名 %type;

变量名 表类型的名字;

第三步,创建一个游标,读取某个查询的结果

cursor 游标名字 is select 查询语句 ;

第四步,打开游标

open 游标名字;

第五步,捕获游标的数据,将内容给到表类型的变量进行保存

fetch 游标名字 bulk collect into 变量名字 ;

第六步,使用 forall 语句,对数据进行批量的操作

forall i in 变量 .first .. 变量 .last DML 语句操作 ;

第七步,关闭游标

close 游标名字 ;

declare

-- 创建表类型

type biao is table of emp_liebiao.ename%type;

b biao;

-- 创建游标

cursor m is select ename from emp_liebiao;

begin

-- 打开游标

open m;

-- 将游标的内容批量的给到变量

fetch m bulk collect into b;

-- 使用forall批量修改数据

forall i in b.first .. b.last insert into ename_emp values(lower(b(i)));

commit;

-- 关闭游标

close m;

end;

练习:批量修改用户的编号,让编号+工资等级+部门,形成一个新的编号,存入下面的表格中,使用 bulk collect 来实现。

2000以下是 C ,2000-3000是 B ,3000以上是 A ,

例如 SMITH , 新编号应该是 7369_C_20

create table empno_emp(

empno varchar2(50)

);

declare

type biao is table of emp_liebiao%rowtype;

b biao;

cursor m is select * from emp_liebiao;

begin

open m;

fetch m bulk collect into b;

forall i in b.first..b.last

insert into empno_emp values(

b(i).empno||'_'||decode(sign(b(i).sal-2000)+sign(b(i).sal-3000),-2,'C',2,'A','B')||'_'||b(i).deptno

);

commit;

close m;

end;

Oracle游标求解决方案

1、创建表

1)创建未核销台账表x01:序列(主键)、票据起始号、票据结束号;

2)创建未核销台账明细表x02:序号、票据号(全表主键);

2、存储过程写台账表

1)查询出未核销台账中最大的票据号和最小的票据号;

2)定义:序号(默认1)、票据起始号(默认最小票据号)、结束号、是否新序号(默认是)

2)游标查询最大票据号和最小票据号之间的所有票据号及核销状态(包括已核销和作废的)

3)逐条判断票据的核销状态

a 核销状态为未核销,是否新序号为是,则

为表x01插入数据:序号、票据起始号、票据结束号(等于当前票据号);

为表x02插入数据:序号、票据号;

是否新序号写成否

b 核销状态为未核销,是否新序号为否,则

为表x01更新数据:票据结束号等于当前票据号(条件是序号等于当前序号);

为表x02插入数据:序号、票据号;

b 核销状态为已核销或作废,是否新序号为是,则

不处理,继续循环;

b 核销状态为已核销或作废,是否新序号为否,则

变量序号加1,是否新序号写成是

4)提交

3、检索表X01,X02,得到 未核销台账表,以及对应的未核销台账明细

oracle 游标能用别的替换或者如何使游标的

你说的资料上说的尽量不使用游标,那就是使用动态sql+execute immediate的方式了。这主要是程序设计上的问题,比如说一些表名或者字段名,可以使用变量来代替,这样写程序的时候麻烦点,但是方便日后维护。取数据用游标没什么错误,看你的存储过程,重要的是还是优化sql。或者可以使用bulk collect 批量的方式取数据。


名称栏目:oracle游标如何优化,oracle游标怎么使用
文章地址:http://azwzsj.com/article/hchhgj.html