什么时候会发生回调(recursive calls)

recursive calls并不仅仅发生在解析的时候。由于数据字典记录了所有对象的结构、数据信息,因此在对象结构(如dba_tables、dba_objects)、数据发生变化(如统计信息的视图、段视图dba_segments(即占用空间会变化))时都会访问数据字典

1.1.4.2.            字典缓存(Dictionary Cache)

 

数据字典是有关于数据库的参考信息、数据库的结构信息和数据库中的用户信息的一组表和视图的集合,如我们常用到的V$视图、DBA_视图都属于数据字典。在SQL语句解析的过程中,Oracle可以非常迅速的访问(如果需要的话)这些数据字典,在SQL Trace中,这种对数据字典的访问就被统计为回调(recursive calls)。看下面例子:

第一调用语句,需要做硬解析:

SQL> select * from T_COMPANY;
 
9999 rows selected.
 
 
Execution Plan
----------------------------------------------------------
Plan hash value: 3356521258
 
-------------------------------------------------------------------------------
| Id  | Operation         | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |           | 10000 |   156K|     9   (0)| 00:00:01 |
|   1 |  TABLE ACCESS FULL| T_COMPANY | 10000 |   156K|     9   (0)| 00:00:01 |
-------------------------------------------------------------------------------
 
 
Statistics
----------------------------------------------------------
        355  recursive calls
          0  db block gets
        764  consistent gets
         39  physical reads
        116  redo size
     305479  bytes sent via SQL*Net to client
       7711  bytes received via SQL*Net from client
        668  SQL*Net roundtrips to/from client
          5  sorts (memory)
          0  sorts (disk)
       9999  rows processed
 

可以看到,Recursive Calls高达355。第二次调用,无需解析,直接使用共享SQL区中缓存:

SQL> /
 
9999 rows selected.
 
 
Execution Plan
----------------------------------------------------------
Plan hash value: 3356521258
 
-------------------------------------------------------------------------------
| Id  | Operation         | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |           | 10000 |   156K|     9   (0)| 00:00:01 |
|   1 |  TABLE ACCESS FULL| T_COMPANY | 10000 |   156K|     9   (0)| 00:00:01 |
-------------------------------------------------------------------------------
 
 
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
        705  consistent gets
          0  physical reads
          0  redo size
     305479  bytes sent via SQL*Net to client
       7711  bytes received via SQL*Net from client
        668  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
       9999  rows processed

由于没做解析,这时recursive calls为0。

当然,recursive calls并不仅仅发生在解析的时候。由于数据字典记录了所有对象的结构、数据信息,因此在对象结构(如dba_tables、dba_objects)、数据发生变化(如统计信息的视图、段视图dba_segments(即占用空间会变化))时都会访问数据字典:

SQL> delete from t_company where rownum=1;
 
1 row deleted.
 
 
...
 
 
Statistics
----------------------------------------------------------
        360  recursive calls
...
 
SQL> /
 
1 row deleted.
 
 
...
 
 
Statistics
----------------------------------------------------------
          4  recursive calls
...
 
SQL> /
 
...
 
Statistics
----------------------------------------------------------
          4  recursive calls
...

可以看到,上面的delete语句在第一次执行时,包括因(SQL语句)解析数据改动导致对数据字典的访问,因此

recursive calls较高,为360。在随后的执行中,因为没有做(SQL语句)解析,所以recursive calls大大减少,只有

4,而这4个recursive calls是因为数据改变而需要对数据字典的访问。


因为Oracle对数据字典访问如此频繁,因此内存中有两处地方被专门用于存放数据字典

一个地方就是数据字典缓存(Data Dictionary Cache)。数据字典缓存也被称为行缓存(Row Cache),因为它是以记录行为单元存储数据的,而不像Buffer Cache是以数据块为单元存储数据。

内存中另外一个存储数据字典的地方是库缓存

所有Oracle的用户都可以访问这两个地方以获取数据字典信息。

你可能感兴趣的:(什么时候会发生回调(recursive calls))