`
tooby
  • 浏览: 118267 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Oracle 视图 v$sql,v$sqlarea,$sqltext,v$sqltext_with_newlines 的差异

    博客分类:
  • SQL
 
阅读更多

视图 v$sql,v$sqlarea,v$sqltext,v$sqltext_with_newlines 是几个经常容易混淆的视图,主要是提供library cache中当前缓存的sql语句的信息。这几个视图都可以提供当前有关sql语句的具体信息,但稍有差异。本文主要描述其差异并给出实例。

 

一、sql语句与游标
      sql语句,这个没什么好说的,就是按照sql标准书写的sql语句
      游标,包含shared cursor,session cursor,简单点来理解,一条sql语句对应一个或多个游标,且一条sql语句至少解析为一个游标。

      当任一sql语句被解析到shared_pool中之后,必定会产生相应的游标,有下列三种情形,
          a、存在可完全共享的父游标
          b、父游标存在,但是由于执行环境的变化,不得不生存新的子游标
          c、没有父游标存在,需要生成全新的游标
      对于情形a,由于存在可共享的父游标,也就是说v$sql中必定已经存在一个对应的sql游标,我们可以查询到,执行之后对应executions及相关列会发生变化。
      对于情形b或c,sql语句产生的游标会被添加到v$sql视图,也即是新增游标(b为新增子游标,c为新增父游标)。

      注:在shared_pool由于aged out原则后的sql可能无法在该视图查询到,这个是另外一个话题。

 

二、视图差异
1、v$sql视图
      假定用户A与用户B都基于自身schema创建了表t
      用户A发布查询select * from t,此时共享池中产生一条与该语句的相关的sql游标,在v$sql视图体现(假定为首次执行)
      不久用户B也发出select * from t的查询,同上,v$sql中也对应有一条该语句的游标
      为了便于理解,我们将v$sql视图中的sql文本称之为游标,将v$sqlarea中的sql文本称为sql语句

2、v$sqlarea
      对于上述情形
      此时v$sqlarea则是对视图v$sql的一个聚合,也即是相当于对视图v$sql使用了distinct关键字。
      尽管v$sql中出现了两条select * from t,而v$sqlarea仅为一条
      v$sqlarea提供的是每条sql语句执行的汇总信息

3、v$sqltext
      该视图包括Shared pool中SQL语句的完整文本,但一条SQL语句是被分成多个块来进行保存的。
      对于比较短的sql语句,一个piece就搞定,对于比较长的sql语句则需要多个piece的结合来完整展现一条真正的sql语句。

4、v$sqltext_with_newlines
      该视图用于完整保存SQL语句所有字符,保留SQL语句的回车和制表符。

 

三、示例说明

1、创建演示环境
SQL> select * from v$version where rownum<2;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production

SQL> create table t ( x varchar2(30) primary key, y int );

SQL> exec dbms_stats.set_table_stats('SCOTT','T', numrows => 1000000, numblks=>100000);

SQL> alter system flush shared_pool;

SQL> select sql_text from v$sql where upper(sql_text) like 'SELECT % T LOOK_FOR_ME%'
  2  and upper(sql_text) not like '%FROM V$SQL%';

no rows selected

2、产生sql游标
SQL> declare
  2     l_x_number      number;
  3     l_x_string  varchar2(30);
  4  begin
  5     execute immediate 'alter session set optimizer_mode=all_rows';
  6     for x in (select * from t look_for_me where x = l_x_number) loop null; end loop;
  7     for x in (select * from t look_for_me where x = l_x_string) loop null; end loop;
  8     execute immediate 'alter session set optimizer_mode=first_rows';
  9     for x in (select * from t look_for_me where x = l_x_number) loop null; end loop;
 10     for x in (select * from t look_for_me where x = l_x_string) loop null; end loop;
 11  end;
 12  /

PL/SQL procedure successfully completed.

3、分析 
SQL> col sql_text format a55
SQL> set linesize 180
SQL> col plan_table_output format a80 truncate
SQL> col sql_id new_val sql_id
SQL> select sql_id, sql_text from v$sql where upper(sql_text) like 'SELECT % T LOOK_FOR_ME %B1_';

SQL_ID        SQL_TEXT
------------- -------------------------------------------------------
1qqtru155tyz8 SELECT * FROM T LOOK_FOR_ME WHERE X = :B1
1qqtru155tyz8 SELECT * FROM T LOOK_FOR_ME WHERE X = :B1
1qqtru155tyz8 SELECT * FROM T LOOK_FOR_ME WHERE X = :B1
1qqtru155tyz8 SELECT * FROM T LOOK_FOR_ME WHERE X = :B1

--从上面的查询可知,对于上面的SQL语句我们得到了相同的SQL_ID。这是因为SQL_ID是由SQL文本hash得到的一个值
--只要SQL文本相同(完全相同),则SQL_ID一定是相同的。

--我们从v$sql视图里边查询得到了四条相同sql_id的sql语句,也即是四个不同的游标
--为什么同样的sql文本产生了四个不同的游标呢?这是因为:
-- cursor 1) 使用ALL_ROWS 优化器模式, 绑定变量为number类型
-- cursor 2) 使用ALL_ROWS 优化器模式, 绑定变量为varchar2类型
-- cursor 3) 使用FIRST_ROWS 优化器模式, 绑定变量为number类型  
-- cursor 4) 使用FIRST_ROWS 优化器模式,绑定变量为varchar2类型

--查询v$sql视图
SQL> select sql_id,loaded_versions,executions,optimizer_mode, plan_hash_value,child_number,child_address
  2  from v$sql where sql_id = '&sql_id';
old   2: from v$sql where sql_id = '&sql_id'
new   2: from v$sql where sql_id = '1qqtru155tyz8'

SQL_ID        LOADED_VERSIONS EXECUTIONS OPTIMIZER_ PLAN_HASH_VALUE CHILD_NUMBER CHILD_ADDRESS
------------- --------------- ---------- ---------- --------------- ------------ ----------------
1qqtru155tyz8               1          1 ALL_ROWS        1601196873            0 0000000081111008
1qqtru155tyz8               1          1 ALL_ROWS        2572036781            1 00000000841B1DD8
1qqtru155tyz8               1          1 FIRST_ROWS      1601196873            2 00000000813D1A70
1qqtru155tyz8               1          1 FIRST_ROWS      2572036781            3 000000007FFE3370

--从上面的查询结果知,optimizer_mode不同,plan_hash_value的值不同,child_address的值也不同
--尤其是child_address表明是pin到shared_pool中不同的位置

--查看v$sqlarea视图
SQL> select sql_id,sql_text,version_count vs_cnt,loaded_versions ld_vs,executions ex_cnt
  2  from v$sqlarea where sql_id = '&sql_id';
old   2: from v$sqlarea where sql_id = '&sql_id'
new   2: from v$sqlarea where sql_id = '1qqtru155tyz8'

SQL_ID        SQL_TEXT                                        VS_CNT      LD_VS     EX_CNT
------------- ------------------------------------------- ---------- ---------- ----------
1qqtru155tyz8 SELECT * FROM T LOOK_FOR_ME WHERE X = :B1            4          4          4

--从上面的视图可知,是sql_id的一个聚合,列出了version_count以及executions的总次数等

--下面来看看每个sql对应的执行计划
--child_number为0的游标,此时为父游标
SQL> select * from table(dbms_xplan.display_cursor('&sql_id',0));
old   1: select * from table(dbms_xplan.display_cursor('&sql_id',0))
new   1: select * from table(dbms_xplan.display_cursor('1qqtru155tyz8',0))

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
SQL_ID  1qqtru155tyz8, child number 0
-------------------------------------
SELECT * FROM T LOOK_FOR_ME WHERE X = :B1

Plan hash value: 1601196873

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |       |       | 28616 (100)|          |
|*  1 |  TABLE ACCESS FULL| T    | 10000 |   292K| 28616   (6)| 00:05:44 |
--------------------------------------------------------------------------------
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter(TO_NUMBER("X")=:B1)  -->存在谓词转换

--下面是child_number为1的子游标
SQL> select * from table(dbms_xplan.display_cursor('&sql_id',1));
old   1: select * from table(dbms_xplan.display_cursor('&sql_id',1))
new   1: select * from table(dbms_xplan.display_cursor('1qqtru155tyz8',1))

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
SQL_ID  1qqtru155tyz8, child number 1
-------------------------------------
SELECT * FROM T LOOK_FOR_ME WHERE X = :B1

Plan hash value: 2572036781

--------------------------------------------------------------------------------
| Id  | Operation                   | Name         | Rows  | Bytes | Cost (%CPU)
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |              |       |       |     2 (100)
|   1 |  TABLE ACCESS BY INDEX ROWID| T            |     1 |    30 |     2   (0)
|*  2 |   INDEX UNIQUE SCAN         | SYS_C0011143 |     1 |       |     1   (0)
--------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("X"=:B1)   

--从上面的两个执行计划中可以看出,因为绑定变量的类型不同,导致了sql语句产生了不同的执行计划
--且第一个执行计划中使用了隐式转换

--下面是child_number为2的子游标的执行计划
--Author : Robinson
--Blog   : http://blog.csdn.net/robinson_0612

SQL> select * from table(dbms_xplan.display_cursor('&sql_id',2));
old   1: select * from table(dbms_xplan.display_cursor('&sql_id',2))
new   1: select * from table(dbms_xplan.display_cursor('1qqtru155tyz8',2))

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
SQL_ID  1qqtru155tyz8, child number 2
-------------------------------------
SELECT * FROM T LOOK_FOR_ME WHERE X = :B1

Plan hash value: 1601196873

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |       |       | 28616 (100)|          |
|*  1 |  TABLE ACCESS FULL| T    | 10000 |   292K| 28616   (6)| 00:05:44 |
--------------------------------------------------------------------------------
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter(TO_NUMBER("X")=:B1)

--下面是child_number为3的子游标的执行计划
SQL> select * from table(dbms_xplan.display_cursor('&sql_id',3));
old   1: select * from table(dbms_xplan.display_cursor('&sql_id',3))
new   1: select * from table(dbms_xplan.display_cursor('1qqtru155tyz8',3))

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
SQL_ID  1qqtru155tyz8, child number 3
-------------------------------------
SELECT * FROM T LOOK_FOR_ME WHERE X = :B1

Plan hash value: 2572036781

--------------------------------------------------------------------------------
| Id  | Operation                   | Name         | Rows  | Bytes | Cost (%CPU)
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |              |       |       |     2 (100)
|   1 |  TABLE ACCESS BY INDEX ROWID| T            |     1 |    30 |     2   (0)
|*  2 |   INDEX UNIQUE SCAN         | SYS_C0011143 |     1 |       |     1   (0)
--------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("X"=:B1)

--子游标2与子游标3也是使用了不同的执行计划,这个原因与父游标0,子游标1的原因相同
--子游标2与父游标0有相同的执行计划,从Plan hash value的值可知
--同样,子游标3与父游标1也有相同的执行计划,从Plan hash value的值可知

--产生不同执行计划的原因
--v$sql_shared_cursor视图记录了那些不能共享子游标的记录并给给出原因,如下查询
SQL> SELECT child_number,bind_mismatch, optimizer_mode_mismatch 
  2  from v$sql_shared_cursor
  3  where sql_id = '&SQL_ID';
old   3: where sql_id = '&SQL_ID'
new   3: where sql_id = '1qqtru155tyz8'

CHILD_NUMBER B O
------------ - -
           0 N N
           1 Y N
           2 N Y
           3 Y Y

--从上面的查询结果可知,游标1与父游标0是由于绑定变量不匹配而导致了不可共享子游标
--游标2则是由于不同的执行环境,游标3则是不同的执行环境与不匹配的绑定变量导致不可共享子游标           

--从上面的测试可以,父游标相同,子游标不同,执行计划可能相同,也可能不相同 
--下面的这个查询也说明了这个问题,得到的是不同的PLAN_HASH_VALUE  
SQL> select a.snap_id, a.sql_id, a.plan_hash_value,to_char(b.begin_interval_time,'yyyy-mm-dd hh24:mi:ss')
  2  from dba_hist_sqlstat a, dba_hist_snapshot b 
  3  where a.snap_id = b.snap_id
  4  and sql_id ='&sql_id';
old   4: and sql_id ='&sql_id'
new   4: and sql_id ='1qqtru155tyz8'

   SNAP_ID SQL_ID        PLAN_HASH_VALUE TO_CHAR(B.BEGIN_INT
---------- ------------- --------------- -------------------
       275 1qqtru155tyz8      1601196873 2013-03-08 12:00:25
       275 1qqtru155tyz8      2572036781 2013-03-08 12:00:25


四、小结
    a、本文讨论了v$sql,v$sqlarea,v$sqltext以及v$sqltext_with_newlines几个视图的差异
    b、需要记住的是v$sql存储所有游标,v$sqlarea等同于使用了distinct关键字,仅保留sql语句。v$sqltext提供完整的sql语句
    c、硬解析通常是由于不可共享的父游标造成的,如经常变动的SQL语句,或动态SQL或未使用绑定变量等
    d、与父游标SQL文本完全一致的情形下,多个相同的SQL语句可以共享一个父游标
    e、SQL文本、执行环境完全一致的情形下,子游标能够被共享,否则如果执行环境不一致则生成新的子游标
    f、父游标相同,子游标不同,执行计划可能相同,也可能不相同

 

五、相关参考
    父游标、子游标及共享游标
    绑定变量及其优缺点
    Oracle 硬解析与软解析
    Oracle 绑定变量窥探
    Oracle自适应共享游标
    Whats the difference between the v$sql* views

 

六、 更多参考:

有关Oracle RAC请参考
     使用crs_setperm修改RAC资源的所有者及权限
     使用crs_profile管理RAC资源配置文件
     RAC 数据库的启动与关闭
     再说 Oracle RAC services
     Services in Oracle Database 10g
     Migrate datbase from single instance to Oracle RAC
     Oracle RAC 连接到指定实例
     Oracle RAC 负载均衡测试(结合服务器端与客户端)
     Oracle RAC 服务器端连接负载均衡(Load Balance)
     Oracle RAC 客户端连接负载均衡(Load Balance)
     ORACLE RAC 下非缺省端口监听配置(listener.ora tnsnames.ora)
     ORACLE RAC 监听配置 (listener.ora tnsnames.ora)
      配置 RAC 负载均衡与故障转移
     CRS-1006 , CRS-0215 故障一例  
     基于Linux (RHEL 5.5) 安装Oracle 10g RAC
     使用 runcluvfy 校验Oracle RAC安装环境

有关Oracle 网络配置相关基础以及概念性的问题请参考:
     配置非默认端口的动态服务注册
     配置sqlnet.ora限制IP访问Oracle
     Oracle 监听器日志配置与管理
     设置 Oracle 监听器密码(LISTENER)
     配置ORACLE 客户端连接到数据库

有关基于用户管理的备份和备份恢复的概念请参考
     Oracle 冷备份
     Oracle 热备份
     Oracle 备份恢复概念
     Oracle 实例恢复
     Oracle 基于用户管理恢复的处理
     SYSTEM 表空间管理及备份恢复
     SYSAUX表空间管理及恢复
     Oracle 基于备份控制文件的恢复(unsing backup controlfile)

有关RMAN的备份恢复与管理请参考
     RMAN 概述及其体系结构
     RMAN 配置、监控与管理
     RMAN 备份详解
     RMAN 还原与恢复
     RMAN catalog 的创建和使用
     基于catalog 创建RMAN存储脚本
     基于catalog 的RMAN 备份与恢复
     RMAN 备份路径困惑
     使用RMAN实现异机备份恢复(WIN平台)
     使用RMAN迁移文件系统数据库到ASM
     linux 下RMAN备份shell脚本
     使用RMAN迁移数据库到异机

有关ORACLE体系结构请参考
     Oracle 表空间与数据文件
     Oracle 密码文件
     Oracle 参数文件
     Oracle 联机重做日志文件(ONLINE LOG FILE)
     Oracle 控制文件(CONTROLFILE)
     Oracle 归档日志
     Oracle 回滚(ROLLBACK)和撤销(UNDO)
     Oracle 数据库实例启动关闭过程
     Oracle 10g SGA 的自动化管理
     Oracle 实例和Oracle数据库(Oracle体系结构)

分享到:
评论

相关推荐

    Oracle v$sqlarea, v$sql, v$sqltext视图说明

    简单描述Oracle v$sqlarea, v$sql, v$sqltext视图说明

    oracle_V$SQLAREA_.rar_oracle_oracle V$sqlarea

    标题中的"oracle_V$SQLAREA_.rar_oracle_oracle V$sqlarea"暗示了这是一个关于`V$SQLAREA`视图的资源压缩包,可能包含了相关查询和解释的文本文件。 `V$SQLAREA`视图包含的数据涵盖了SQL语句的多个方面,如: 1. *...

    oracle_v$session_v$session_wait用途详解

    SELECT * FROM v$sqltext WHERE address = :sql_address AND hash_value = :sql_hash_value; ``` - **行等待信息查询** - 通过 `ROW_WAIT_OBJ#`, `ROW_WAIT_FILE#`, `ROW_WAIT_BLOCK#`, `ROW_WAIT_ROW#` 可以...

    oraclev$sessionv$session_wait用途详解

    3. **等待原因**:结合`v$session_wait`与其他视图(如`v$lock`、`v$sqltext`),可以深入分析等待事件的具体原因,例如锁定冲突的根源或慢SQL语句。 ### 使用示例与场景 - **性能调优**:当数据库响应变慢时,...

    Oracle的V$性能视图学习大全

    此外,V$视图家族中的V$SQLAREA、V$SQLTEXT、V$SESSION和V$SESS_IO等视图,可以用来查询和分析SQL语句的执行状态和性能。通过这些视图,DBA可以识别出执行时间长、占用资源多的SQL查询,进而对查询语句进行优化。 ...

    oracle 动态性能(V$)视图

    1. **执行计划分析**:如V$SQL、V$SQLAREA和V$SQLTEXT,这些视图存储了SQL语句的相关信息,包括执行计划、统计信息和绑定变量等,对SQL性能分析至关重要。 2. **资源使用情况**:V$SESSION、V$SESSION_WAIT和V$...

    用Oracle动态性能视图采集查询调优数

    V$SQLTEXT和V$SQLTEXT_WITH_NEWLINES视图则是为了获取SQL语句的逐行表示,适合于查看和分析具体的SQL语法结构。V$SQLTEXT_WITH_NEWLINES保留了原始的换行符,提高了可读性,而V$SQLTEXT则用空格替换换行符,使数据更...

    查找运行系统里bad sql

    6. 使用 V$SQLTEXT_WITH_NEWLINES 视图查看当前用户&username 执行的 SQL。可以使用以下 SQL 语句查找: ``` select sql_text from v$sqltext_with_newlines where (hash_value, address) in ( select sql_hash_...

    oracle 查看当前会话执行的sql语句

    这里使用了`sql_hash_value`字段来关联`v$session`和`v$sqltext`两个视图,其中`&sid`是一个输入参数,代表了要查询的会话的SID。`order by piece asc`是为了按照SQL语句的片段顺序排列。 #### 3. 监控当前会话的...

    oracle监听执行sql语句

    这条SQL语句通过连接`v$session`和`v$sqlarea`两个视图来获取当前会话中执行的SQL语句及其完整文本。其中`v$session`包含了所有活动会话的信息,而`v$sqlarea`则存储了最近执行过的SQL语句的元数据。通过`a.sql_...

    Oracle性能视图学习大全

    5. **分析SQL执行效率**:通过查询`V$SQLAREA`、`V$SQLTEXT`等视图,可以定位执行效率低下的SQL语句,并对其进行优化。同时,结合`V$SESSION`和`V$SESS_IO`视图,可以进一步分析特定会话的资源消耗情况。 6. **识别...

    Oracle动态性能视图

    - **V$SQLAREA**、**V$SQLTEXT**、**V$SESSION** 和 **V$SESS_IO**:用于查找可能存在问题的查询。 5. **用户活动** - **V$SESSION**:检查用户的当前操作及其使用的资源。 - **V$SESSION_WAIT**、**V$SESSION_...

    oracle标准语法速查表

    v$sql, v$sqlarea, v$sqltext, v$sqltext_with_newlines - **定义**:SQL语句的信息。 - **用途**:查看执行过的SQL语句详情。 ##### 16. v$sql_cursor, v$sql_bind_data, v$sql_bind_metadata - **定义**:游标、...

    常用oracle动态性能视图

    - 通过 SQL 相关列(如 SQL_HASH_VALUE 和 SQL_ADDRESS),可以与 V$SQLTEXT、V$SQLAREA 和 V$SQL 视图联接,查看具体执行的 SQL 语句内容。 4. **示例查询:** - 查询当前会话信息:`SELECT SID, OSUSER, ...

    定位Oracle中的topsql[总结].pdf

    可以通过查询 V$SQLAREA 视图,按照 buffer_gets 和 disk_reads 两个字段排序,找到资源消耗最大的 SQL 语句。 ```sql SELECT b.username username, a.sql_id, a.executions exec, a.buffer_gets buffer, ...

    学些动态性能表-word版

    学习动态性能表(四)--v$sqltext&v$sqlarea 学习动态性能表(五)--v$session 学习动态性能表(六)--v$session_wait&v$session_event 学习动态性能表(七)--v$process 学习动态性能表(八)--v$lock&v$locked_object ...

    oracle最重要的9个动态性能视图

    `v$sqltext` 视图则显示了具体的SQL文本内容,与`v$sql`视图结合使用时,可以详细地分析SQL语句及其执行效率。 ### 4. v$bh (原 x$bh) `v$bh`(或其内部视图`x$bh`)用于查询块缓存的信息。这对于理解数据块在缓冲...

    SQL优化器相关知识 精品资料.pptx

    V$SQL、V$SQLAREA、V$SQLTEXT视图可以提供SQL语句的执行计划信息,例如: 1. V$SQL视图:提供SQL语句的执行计划信息,包括执行计划的详细信息和执行统计信息。 2. V$SQLAREA视图:提供SQL语句的执行计划信息,包括...

    Oracle SQL 官方文档

    Oracle SQL 是一种强大的数据库查询和编程语言,广泛用于管理和操作Oracle数据库系统。11g第二版(11G2)是Oracle的一个重要版本,提供了许多增强功能和优化。本官方文档集包括四份重要的参考资料,涵盖了Oracle SQL...

Global site tag (gtag.js) - Google Analytics