您的位置:首页 > Web前端

select语句的结果集直接发向客户端的(一个SQL语句会前后进行各种调用,包括解析(parse)调用、执行(executive)调用、获取(fetch)调用)

2014-08-12 10:55 1156 查看
napolone1983

oracle执行select操作,返回的结果集存放在什么位置?结果集中保存的是rowid集合还是真实的数据?返回的结果集是放在PGA区域么?如果返回的是真实的数据,那么如果数据量过大会不会造成内存溢出?请各位高手解答

Yong Huang

If it's a simple select * from table, the data goes straight to the client. If the SQL has some intermediate steps for data processing, such as select count(*) from table, UGA will be used. In dedicated config, UGA is part of PGA.

napolone1983

Yong Huang 发表于 2011-10-28 22:52



If it's a simple select * from table, the data goes straight to the client. If the SQL has some inte ...

有些迷茫啊,我查询10万条数据(一个简单的select语句),难道也直接返回到客户端么?如果所有的结果集直接返回到客户端,那要游标干什么啊?

我原本理解的是:游标中会保存查询结果集的rowid信息,而结果集所需要的数据块被载入到了SGA中,当用户通过游标顺序读取的时候,游标才从SGA的缓存数据块中获取行记录,如果结果集较大或者说需要载入的数据块交多,oracle可能会使用虚拟内存。

请各位牛人帮忙解释一下,我上述描述是否正确?

sundog315

对于直接获取的数据(不是指direct path read所得的数据,而是对应于这句话:If it's a simple select * from table, the data goes straight to the client.),没有必要额外存放,数据已经在那里(buffer cache:logical read / disk:phisical read)

对于中间结果,例如Huang版说的,或者,排序结果、数组之类的,应该在PGA或磁盘中

Yong Huang

> 游标中会保存查询结果集的rowid信息,而结果集所需要的数据块被载入到了SGA中

Of course the data blocks will be scanned into SGA (buffer cache specifically), unless it's a direct path read. Your original question is whether the data will be in PGA. I already answered that. But no matter whether it's select *... or select count(*) ...,
the table data must go to the buffer cache first (except for parallel read, and a few other special cases of direct path read).

Yong Huang

napolone1983

Yong Huang 发表于 2011-10-31 23:39



> 游标中会保存查询结果集的rowid信息,而结果集所需要的数据块被载入到了SGA中

Of course the data blo ...

总觉得各位跟我问的问题有些出入,可能是我描述的不准确,我再精简一下:

(1)相关结果的数据块被载入到了SGA,俺么如果数据量过大(超出了SGA的容量),oracle如何解决?

(2)如果用OO分析的话,游标有哪些属性,哪些方法?或者说游标是如何从数据块中抽取行记录信息的?

请各位高手直接回到我上面的问题就可以了,其他的有时间再请教!!!!!

Yong Huang

It's quite common to have more data fetched than the SGA (buffer cache) can hold. Oracle simply sends the first batch of data to the client, "age out" older blocks in the buffer cache to make room for new blocks, read more blocks from datafiles to cache,
and send them to the client.

What is "OO分析"?

Yong Huang

napolone1983

非常感谢!!

What is "OO分析"?就是“面向对象”分析,如果把游标看成一个对象来看的话,他有哪些属性以及哪些方法?

Yong Huang

> 如果把游标看成一个对象来看的话,他有哪些属性以及哪些方法?

You can see properties of a cursor by reading definitions of the columns of v$sql view( Here I'm talking about the cursor in the library cache of the shared pool.).
Methods that can be applied to a cursor are only a few,(比如) open, fetch, execute.

Check the procedures in package dbms_sql(You may be talking about that as inPL/SQL code, "declare cursor
...", or the cursor in dbms_sql).

Yong Huang

gclizh

napolone1983 发表于 2011-10-30 12:19



多谢回复!

其实我想知道的是结果集查询出来之后,大数据量的存放以及游标读取的过程(按照OO分析的话 ...

数据从服务器返回到客户端不可能是一个数据包发过去的,肯定分了很多批。

我理解游标的结构可能包含: 指向数据字典相关信息的指针,指向执行计划的指针。每个session 访问这个游标的时候 应该还有 当前执行到什么位置的信息。

Yong Huang

> 数据从服务器返回到客户端不可能是一个数据包发过去的,肯定分了很多批。

Only if the number of rows exceeds array size (called by other name in apps other than sqlplus) set by the client, or exceeds other limits set by SQL*Net.

Lower network layer of course also sets packet size.

array size 【即数组大小】(called by other name in apps other than sqlplus,即在sqlplus工具中叫[b]array size的这个概念在别的应用程序中可能有别的名字) set by the client。也还受到SQL*Net层的一些因素的限制。[/b]

> 我理解游标的结构可能包含: 指向数据字典相关信息的指针,指向执行计划的指针。每个session 访问这个游标的时候 应该还有 当前执行到什么位置的信息。

A parsed cursor has no pointer pointing to the data dictionary. But there're pointers pointing to addresses in the shared pool.

Actually, we may be talking about two different meanings of cursor. Here I'm talking about the cursor in the library cache of the shared pool. You may be
talking about that as in PL/SQL code, "declare cursor ...", or the cursor in dbms_sql. I think the properties are shown by some functions in that
package, such as last_row_id, last_row_count, etc.

Yong Huang

附加:

chicheng_cn421

应该是这样的:

当语句执行完成之后,查询到的数据还是在服务器进程中,还没有被传送到客户端的用户进程。所以,在服务器端的进程中,有一个专门负责数据提取的一段代码。他的作用就是把查询到的数据结果返回给用户端进程,从而完成整个查询动作。

========================================================

总结:

(1)相关结果的数据块被载入到了SGA,俺么如果数据量过大(超出了SGA的容量),oracle如何解决?

oracle执行select操作,返回的结果集存放在什么位置?结果集中保存的是rowid集合还是真实的数据?返回的结果集是放在PGA区域么?如果返回的是真实的数据,那么如果数据量过大会不会造成内存溢出?请各位高手解答

If it's a simple select * from table, the data goes straight to the client. If the SQL has some intermediate steps for data processing, such as select count(*) from table, UGA will be used. In dedicated config, UGA is part of PGA.

对于直接获取的数据,没有必要额外存放,数据已经在那里(buffer cache, logical read/disk,phisical read logical read)

对于中间结果,例如Huang版说的,或者,排序结果、数组之类的,应该在PGA或磁盘中

有些迷茫啊,我查询10万条数据(一个简单的select语句),难道也直接返回到客户端么?如果所有的结果集直接返回到客户端,那要游标干什么啊?

我原本理解的是:游标中会保存查询结果集的rowid信息,而结果集所需要的数据块被载入到了SGA中,当用户通过游标顺序读取的时候,游标才从SGA的缓存数据块中获取行记录,如果结果集较大或者说需要载入的数据块交多,oracle可能会使用虚拟内存。

请各位牛人帮忙解释一下,我上述描述是否正确?

> 游标中会保存查询结果集的rowid信息,而结果集所需要的数据块被载入到了SGA中

Of course the data blocks will be scanned into SGA (buffer cache specifically), unless it's a direct path read. Your original question is whether the data will be in PGA. I already answered that. But no matter whether it's select *... or select count(*) ...,
the table data must go to the buffer cache first (except for parallel read, and a few other special cases of direct path read).

Yong Huang

It's quite common to have more data fetched than the SGA (buffer cache) can hold. Oracle simply sends the first batch of data to the client, "age out" older blocks in the buffer cache to make room for new blocks, read more blocks from datafiles to cache,
and send them to the client.

=========

首先,我们要知道服务端的一个服务器进程对客户端上传上来的一个SQL语句会前后进行各种调用,包括解析(parse)调用【涉及到shared pool区域】、执行(executive)调用、获取(fetch)调用。平时,我们所说的执行一个SQL语句,默然指的就是执行(executive)调用,比如,执行完毕一个查询语句select(即执行(executive)调用结束)所获得的结果其实不是除了我们一般以为的含有我们所需的数据的那些数据行,而是还有这些数据行所对应的rowid值的集合。该rowid集合保存在PGA的一块区域上(叫什么名字忘记了,反正就是PL/SQL
code, "declare cursor ..."里所说的游标(客户端上的)所指向的区域)。比如,我们在一个sqlplus上输入一条sql语句后回车所获得的结果集就是执行(executive)调用结束后所得的那些数据行。而这里所得的rowid集合用于什么情况下呢?就是PL/SQL
code, "declare cursor ..."里所说的游标时用到。然后,进行获取(fetch)调用获取(fetch)调用的作用就是通过该rowid集合在SGA的buffer
cache上快速定位到一条数据行并将这些数据行发送到客户端。如果数据行所在的数据块不在SGA的buffer cache上,则先从磁盘上物理读取到SGA的buffer cache上。执行(executive)调用和获取(fetch)调用是一前一后,还是可以在时间上有些重合。chicheng_cn421

应该是这样的:

当语句执行完成之后,查询到的数据还是在服务器进程中,还没有被传送到客户端的用户进程。所以,在服务器端的进程中,有一个专门负责数据提取的一段代码(这里说的代码就是指的是[b]获取(fetch)调用
)。他的作用就是把查询到的数据结果返回给用户端进程,从而完成整个查询动作。】[/b]

数据从服务器返回到客户端是分批发送的,[b]分批发送中的一次发送的数据量为多少取决于客户端的数组大小,即array size 【即数组大小】(called by other name in apps other than sqlplus,即在sqlplus工具中叫array size的这个概念在别的应用程序中可能有别的名字)
set by the client。也还受到SQL*Net层的一些因素的限制。只有当所发送的数据行的行数小于客户端的[b]数组大小[/b]时,数据从服务器返回到客户端才是一次发送的。[/b]

客户端在获取结果集完毕的时间所以也会受到网络传输速度的影响。像sqlplus中set autottrace traceonly时执行select语句所得结果显示里面XXXbytes from sql*net to client,这个不是表明服务端真的发送这么多数据给客户端,实际是没有发送数据到客户端,只是发送了服务端统计的这个结果集的字节数大小([b]XXXbytes from sql*net
to client
)这样一个变量值过来给客户端而已。在执行select语句前set timing on 后,[b]执行该select语句[/b]后所显示的时间为sql语句上传到服务器的时间、解析该语句以及不带发送数据时的执行该语句的时间之和。

[/b]

附加:

随着一个服务器进程对客户端上传上来的一个SQL语句开始进行各种调用(即解析(parse)调用、执行(executive)调用、获取(fetch)调用),一个服务器进程对应的PGA里的CGA(调用全局区)也就会跟着开始创建。换句话说,CGA也是一块内存区域,但它是动态的,即随着调用(call)的开始而创建,在调用过程中一直存在,直到调用结束时被释放它存放的是在调用过程中所需要的数据

简而言之,一个服务器进程对一个SQL语句的操作的过程,就是一个所谓的调用过程。而PGA里的CGA(调用全局区)只存在于该调用过程期间,服务器进程在该调用过程期间才会使用CGA(调用全局区),当然该期间还是会使用PGA的其他区域的。一个服务器进程不会因为对一个SQL语句的操作执行完毕而消失,服务器进程还是依然存在的,在非调用过程期间,服务器进程对应使用的是PGA的其他区域(除了CGA)。

1.3 CGA(调用全局区)的相关概念

CGA也是一块内存区域,但它是动态的,即随着调用(call)的开始而创建,在调用过程中一直存在,直到调用结束时被释放它存放的是在调用过程中所需要的数据
我们知道,调用主要包括解析(parse)调用、执行(executive)调用、获取(fetch)调用以及递归SQL调用和PL/SQL调用。从调用的种类可以看出,实际上在调用过程中所需要的数据,比如SQL
AREA,PL/SQL AREA和SORT AREA基本都是放在UGA中的,因为这些数据在各个调用之间必须一直存在并可用。而在CGA中只存放了在调用过程中临时需要的数据,比如直接I/O缓存(Direct
I/O Buffer)以及堆栈空间等数据结构。因此,没有CGA中的数据结构,调用是无法完成的。
注意,CGA不象UGA可以位于SGA中(以共享服务器模式连接),CGA一定是位于PGA中的。如果当前进程正在运行,则每个PGA中只有一个CGA。如果当前进程没有运行,则该进程的PGA中就没有CGA。

=============

(2)如果用OO分析的话,游标有哪些属性,哪些方法?或者说游标是如何从数据块中抽取行记录信息的?

(3)数据从服务器返回到客户端不可能是一个数据包发过去的,肯定分了很多批。

Only if the number of rows exceeds array size (called by other name in apps other than sqlplus) set by the client, or exceeds other limits set by SQL*Net。

Lower network layer of course also sets packet size。

参考:
http://www.itpub.net/thread-1505871-2-1.html

select语句的结果集可能会存放在pga的UGA区域以及对DML语句中的db block gets direct理解

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐