首页 > Linux操作系统 > Linux操作系统 > 关于执行计划里recursive calls,db block gets和consistent gets等参数的解释

关于执行计划里recursive calls,db block gets和consistent gets等参数的解释

原创 Linux操作系统 作者:DataKW 时间:2013-07-18 10:56:03 0 删除 编辑

在sqlplus使用命令SET AUTOTRACE ON后,执行计划显示如下:

SELECT STATEMENT ptimizer=ALL_ROWS (Cost=985 Card=1 Bytes=26)

35 recursive calls
0 db block gets
1052 consistent gets
7168 physical reads
0 redo size
395 bytes sent via SQL*Net to client
512 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed

其中recursive calls,db block gets,consistent gets的具体含义是什么?


· Recursive Calls. Number of recursive calls generated at both the user and system level. 
Oracle Database maintains tables used for internal processing. When it needs to change these tables, Oracle Database generates an internal SQL statement, which in turn generates a recursive call. 
In short, recursive calls are basically SQL performed on behalf of your SQL. So, if you had to parse the query, for example, you might have had to run some other queries to get data dictionary information. These would be recursive calls. Space management, security checks, calling PL/SQL from SQL—all incur recursive SQL calls. 

· DB Block Gets. Number of times a CURRENT block was requested. 

Current mode blocks are retrieved as they exist right now, not in a consistent read fashion.
Normally, blocks retrieved for a query are retrieved as they existed when the query began. Current mode blocks are retrieved as they exist right now, not from a previous point in time. 
During a SELECT, you might see current mode retrievals due to reading the data dictionary to find the extent information for a table to do a full scan (because you need the "right now" information, not the consistent read). During a modification, you will access the blocks in current mode in order to write to them. 
(DB Block Gets:请求的数据块在buffer能满足的个数)

· Consistent Gets. Number of times a consistent read was requested for a block. 
This is how many blocks you processed in "consistent read" mode. This will include counts of blocks read from the rollback segment in order to roll back a block. 
This is the mode you read blocks in with a SELECT, for example. 
Also, when you do a searched UPDATE/DELETE, you read the blocks in consistent read mode and then get the block in current mode to actually do the modification. 
(Consistent Gets:数据请求总数在回滚段Buffer中)

· Physical Reads. Total number of data blocks read from disk. This number equals the value of "physical reads direct" plus all reads into buffer cache. (Physical Reads:实例启动后,从磁盘读到Buffer Cache数据块数量)

· Sorts (disk). Number of sort operations that required at least one disk write. Sorts that require I/O to disk are quite resource intensive. Try increasing the size of the initialization parameter SORT_AREA_SIZE.

关于 db block gets,consistent gets,physical reads的概念首先来看下官方文档的解释

db block gets:Number of times a CURRENT block was requested. 当前模式所请求读的块数
consistent gets:Number of times a consistent read was requested for a block.   在一致读模式下所读的块数
physical reads:Total number of data blocks read from disk. This number equals the value of "physical reads direct" plus all reads into buffer cache.       从磁盘读的块数 (其大小=物理直接路径读 +从缓冲所获取的块数)

下面来点详细的 其中有些是来自网络上的
db block gets : 
number of data blocks read in CURRENT mode ie) not in a read consistent fashion, but the current version of the data blocks. 产生db_block_gets的主要方式:
1.DML like Update, Delete will need to access the blocks in the current mode for modification. 
2.Most data dictionary calls are done in CURRENT mode. 
3.Buffers are often retrieved in current mode for INSERT, UPDATE, and DELETE, and SELECT FOR UPDATE statements. Blocks must be requested in current mode in order to be changed. 
4.Also certain classes of blocks, like segment header blocks are always requested in current mode. 
5. this will happen when you're doing a FULL TABLE SCAN on a table or a FAST FULL SCAN on an index. In those cases, the segment header is read (usually multiple times for some unknown reason) in current mode.

在current mode模式下产生的对block的访问叫db block gets,这些block在SGA中,不需要访问硬盘。
db_block_gets counts logical reads in CURRENT mode in the buffer cache and also includes direct read blocks (sort-on-disk) blocks.
consistent gets : 
number of data blocks accessed in READ CONSISTENT mode. When a block is requested in consistent mode, if any changes have been committed or made to that block since the requesting statement (or transaction) began, then they must be rolled back for the purposes of the read, to give a consistent view of the data at that time.(当数据库是在consistent mode模式下被请求的,则假如该数据块的数据修改是在查询语句发出之后被提交的,则此查询语句读到该数据块时,还必须为本次查询将数据回滚,得到查询语句发出时该数据块的值,以便给查询给出一个与该查询有关的所有数据块的一致性视图,这也就是oracle所说的一致性读)   In order to maintain statement level read consistency, Oracle has to read the blocks in a consistent fashion(as of the snapshot SCN) and hence may fetch from rollback segments , which is also added to this statistic. Buffers are usually retrieved in consistent mode for queries. 如普通的select语句、索引访问而引起的将数据读入到buffer中(也可能为physical read)或直接从buffer中读数据。注意,DML语句也能引起consistent gets,如update tab1 set col_b='Hello world' where col_a=1;,因为该语句需要找到需要被修改的所有数据块,在找数据块的过程中就会引起consistent gets。
在Read consistent mode模式下产生的对block的访问叫consistent gets。

Session logical read is: The sum of "db block gets" plus "consistent gets".

db_block_changes counts modifications made to CURRENT blocks 
'db block changes' = changes made to current blocks under LOGING ( UPDATE, INSERT, DELETE) + changes made to SORT blocks ( NOLOGING).

'consistent changes' :
changes made to block for CONSISTENT READ and changes made to SORT blocks

physical reads :
Physical( disk and/or filesystem page cache) reads. Basically those that cannot be satisfied by the cache and those that are direct reads.
Total number of data blocks read from disk. This number equals the value of "physical reads direct" (direct from disk, excludes buffer cache) plus all reads into buffer cache.

physical writes :
Total number of data blocks written to disk. This number equals the value of "physical writes direct" (Number of writes directly to disk, bypassing the buffer cache as in a direct load operation) plus all writes from buffer cache.

要注意Oracle 的physical read 与 physical writes并不总是等于硬盘真正意义上的物理读与物理写,因为现在都存在操作系统高速缓存与磁盘子系统高速缓存,这样及时I/O没有被实际写入磁盘,操作系统I/O子系统或磁盘系统也会确认为一个成功的I/O,所以ORACLE 的physical read 与 physical writes并不是物理上发生读写的次数。

redo block size:
redo block size is platform. specific. There is a method to determine the size by dumping the redo header, refer to note 154864.1. Redo blocks written does not include archive writes or multiplexed writes.

redo entries:
The redo log buffer is a circular buffer in the SGA that holds information about changes made to the database. This information is stored in redo entries. Redo entries contain the information necessary to reconstruct, or redo, changes made to the database . Redo entries are used for database recovery, if necessary. 
Redo entries are copied by Oracle server processes from the user's memory space to the redo log buffer in the SGA. (this copy is what the statistic represents).

db block changes包含dml修改的block,也包含为实现rollback功能而修改的block,但是不包含为实现redo功能而修改的block。

the number of blocks visited = consistent gets + db block gets
the number of blocks visited相当与logical read,即从内存中都数据块的次数

这里还有个解释 也很详细 可以综合的看下。。。

A 'consistent get' is your server process telling the database "I need this dba (data block address) consistent with the point in time represented by this SCN, x."

So, lots of things can happen here. First, Oracle will look in the buffer cache for a CR (consistent read) buffer of the block that's consistent w/ the requested SCN. It may find it, if it does, that's counted as a 'consistent get' and either a 'consistent gets - no work' or 'consistent gets - cleanouts only', depending on whether the block needed to be cleaned out. (See V$SYSSTAT/V$SESSTAT for the statistics.) If it doesn't, it may take an existing CR buffer and roll it back further, or it may clone the current block and roll it back. If it needs to apply rollback (aka undo) then it will increment 'consistent gets' and either 'consistent gets - rollbacks only' or 'consistent gets - cleanouts and rollbacks'.

So, each 'consistent get' is your server process successfully getting access to the contents of a dba consistent w/ a particular SCN. This number should represent the number of buffer gets required to satisfy a particular query.

Now, 'db block gets'. A 'db block get' is a copy of the 'current mode block'. That is, the data in the block, as it exists currently, or at this point in time. Note that while multiple CR copies of a block may exist in the buffer cache, there can only ever be one current mode copy of a block in the buffer cache at any one time. (RAC is a special case, w/ shared current and exclusive current, but I'm not going to get into that here.) So, a 'db block get' is a buffer get in current mode. 'db block gets' are usually associated w/ DML, and in that scenario, will implicitly lock one or more rows in that block. Also, there is a notable case where db block gets can occur with a select statement. That will happen when you're doing a FULL TABLE SCAN on a table or a FAST FULL SCAN on an index. In those cases, the segment header is read (usually multiple times for some unknown reason) in current mode.

Next, 'physical reads': A physical read will occur any time a consistent get or a db block get goes looking for block and can't find it in the buffer cache. So, for each block read from disk, physical reads will be incremented. Gets which result in physical reads are counted both as as get and as a read in the statistics. So, if you do 10 consistent gets and 5 of them require physical reads, you should see consistent gets incremented by 10 and physical reads incremented by 5.

Now, what's up w/ arraysize Well, arraysize is the client side setting for SQL*Plus specifying the size of the array that will receive result sets. The default, as you learned, is 15. Now, suppose you have a table where there are 30 records per block, and 3,000 rows in the table. But, your arraysize is 15. So, your server process will get the first 15 rows, and return them from the first block buffer. Now, for the next 15, you need to get that same block again, for rows 16-30. So, you need to do two buffer gets per block to get all the rows. For a 3,000 row table, you'll do (approximately) 3,000/15 = 200 buffer gets. If you change your arraysize to 30, you can get away w/ visitng each block only once and do 3,000/30 = 100 buffer gets.

So, consider that even after you've optimized a particular SQL statement, if the arraysize is too small, you're going to force your server process to do excess database calls (FETCH calls), and extra buffer gets as well. This can best be illustrated with a test similar to what you did, but try looking at the raw trace file for FETCH calls. The number of FETCH calls ought to be very close to (number of rows returned / arraysize). The 'r=xxx' in the FETCH call data in the trace file is the number of rows returned, which is probably what your arraysize is set to.

So, db block gets, consistent gets, and physical reads are all measured in buffers (or blocks). If the same block is requested multiple times, it will be counted that many times in these statistics. Oracle will always access data from the buffer cache by the buffer. All 'get' operations are by the buffer, never by row. After the buffer is 'gotten', Oracle parses the block to get the data for the relevant rows.

When a "consistent get" is done, this doesn't necessarily mean that Oracle had to do any rollback/undo of DML in order to get the consistent image. Rather, it just means that Oracle requested a copy of the block as of the point in time that the query was started (a "consistent snapshot"). So, I believe it is quite normal to have many, many consistent gets even if there is NO DML occuring.

LOGIC IO(逻辑读次数)=db block gets + consistent gets

consistent get : 在一致读模式下所读的快数,包括从回滚段读的快数。
db block gets : 在当前读模式下所读的快数,比较少和特殊,例如数据字典数据获取,在DML中,更改或删除数据是要用到当前读模式。

consistent gets : 通过不带for update的select 读的次数
db block gets : 通过update/delete/select for update读的次数.

consistent gets:consistent_gets是从回滚段中读到的前映(或叫读取一致性影象), 看见的数据是查询开始的时间点的,所以若存在block在查询开始后发生了变化的情况,则必须产生 before image 然后读数据,这就是一致读的含义
查询就是表示 consistent gets (query mode),因为查询要保证所获取的数据的时间点的一致性,所以叫一致读,即使是从当前 buffer 获得的数据,也叫 consistent gets ,这仅仅表达一种模式一种期望,并不表示真实的是从 当前buffer 获得 还是从回滚段获取数据产生的 bufore image 。

db block gets: current mode , 不管这个块上的数据是否可能存在 before image ,也就是说不管是否存在回滚中数据可以 回滚,只看见当前最新块的数据,即使别人正在更新,也看见别人更新状态的数据,比如dml的时候就不需要看见别人更改前的数据,而是看见正在更改的,当然同时,若操作相同数据则被lock住。也就是说一次查询中看见的数据可能不在同一个时间点上,比如一个大的dml,当dml 开始更新一个非常大的表后,这个表更新的过程中,有一个进程去把该表末尾的一个记录更新了,然后这个大更新抵达该记录的时候会被阻塞的,若该进程事物提交,则大更新会覆盖该事务的更新,也就是说,这个大更新所看见的数据是当前的,不具有时间点的一致性,所以叫 current mode,个人认为db block gets这个词用的不好, 容易让人误解. 如果改成inconsistent gets可能会更准确一些

consistent gets
db block gets + consistent gets = logical io (as opposed to physical io). consistent gets are current mode gets. This might entail a reconstruction of the block with the undo (rollback) mechanism.

Number of times a consistent read was requested for a block.

db block gets
db block gets + consistent gets = logical io (as opposed to physical io). db block gets are current mode gets, blocks that are read as they are (even if these are being modified by another session)

Number of times a CURRENT block was requested.

来自 “ ITPUB博客 ” ,链接:,如需转载,请注明出处,否则将追究法律责任。

上一篇: CAP原理和BASE思想
请登录后发表评论 登录


  • 博文量
  • 访问量