ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 区分三个类似视图

区分三个类似视图

原创 Linux操作系统 作者:kewin 时间:2009-03-02 23:05:14 0 删除 编辑

     v$sql, v$sqlarea, v$sqltext的区别
1、先说简单的--v$sqltext中有内存中完整的sql语句,SQL被piece字段分割成64字节的片断,但没有该语句的统计信息,比如执行次数等。
 
SQL> desc v$sqltext
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ADDRESS                                            RAW(8)
 HASH_VALUE                                         NUMBER
 COMMAND_TYPE                                    NUMBER
 PIECE                                                   NUMBER
 SQL_TEXT                                             VARCHAR2(64)

而底层的数据源时 x$kglna,查看其定义为:
select inst_id,kglhdadr, kglnahsh, kgloboct, piece, name from x$kglna where kgloboct != 0

2、v$sql与v$sqlarea这两个视图都包含统计信息,比较容易混淆:

v$sql与v$sqlarea的源都是一个:X$KGLCURSOR
SELECT view_definition FROM v$fixed_view_definition WHERE view_name='GV$SQL';
SELECT view_definition FROM v$fixed_view_definition WHERE view_name='GV$SQLAREA';

通过VIEW_DEFINITION,可以看到
V$SQLAREA 是做了group by:
 group  by inst_id,kglnaobj,kglhdpar,kglnahsh,kglnatim,            kglobts0, kglobt19, kglobts1, kglobt20,             
  decode(kglobt33, 1, 'Y', 'N'), kglhdclt    having sum(decode(kglobt09,0,kglobt02,0)) != 0

而V$SQL WHERE 语句 仅仅是做了条件过滤:
from x$kglcursor  where
 kglhdadr != kglhdpar  and   kglobt02 != 0

v$sql join to v$sql_plan就代表了具体的SQL执行计划。
关联字段:
ADDRESS RAW(4)
HASH_VALUE NUMBER
CHILD_NUMBER NUMBER

在10G,可以通过 SQL_ID直接关联两张视图,比9i简化多了。

即使是相同的数据库用户,若 session 的优化模式、session 级的参数 等不一样,相同内容的SQL,其执行计划也能不同。
v$sql能记录下这些不同执行计划的SQL语句。
而v$sqlarea忽略了执行计划等差异,只是在形式上sql文本看起来一样。相当于做了个聚合,是多个不同执行计划的sql的聚合和累计信息
具体一点:v$sqlarea相当于是按INST_ID, KGLNAOBJ, KGLHDPAR, KGLNAHSH, KGLNATIM, GLOBTS0,GLOBT19, KGLOBTS1, KGLOBT20,DECODE(KGLOBT33, 1, 'Y', 'N'),KGLHDCLT这些列的自v$sql的group by,也就是说v$sql的每一行表示的是每一个sql语句的一个version,而v$sqlarea存放的是相同语句不同version一个汇总。
实际调优中建议使用v$sql,相对来说比v$sqlarea快,而且还不会产生share pool latch的争用。
下面做个测试:
环境搭建:
SQL> desc t
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 I                                                  NUMBER(38)

SQL> select * from t;

         I
----------
       200
       100

SQL> var dd  number;
SQL> begin
  2  :dd := 100;
  3  end;
  4  /

PL/SQL procedure successfully completed.

SQL>
SQL> select count(*) from t lookup_me  where i = :dd;

  COUNT(*)
----------
         1

SQL> show parameter optim

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
object_cache_optimal_size            integer     102400
optimizer_dynamic_sampling           integer     1
optimizer_features_enable            string      9.2.0
optimizer_index_caching              integer     0
optimizer_index_cost_adj             integer     100
optimizer_max_permutations           integer     2000
optimizer_mode                       string      CHOOSE
SQL> alter
  2 
SQL> alter session set optimizer_mode=first_rows;

SQL> begin
  2  :dd := 200;
  3  end;
  4  /

PL/SQL procedure successfully completed.

SQL> select count(*) from t lookup_me  where i = :dd;

  COUNT(*)
----------
         1

SQL> select address,hash_value, child_number , sql_text
  2  from v$sql
  where upper(sql_text)
  like
  'SELECT % T LOOKUP_ME %';  3    4    5 

ADDRESS          HASH_VALUE CHILD_NUMBER
---------------- ---------- ------------
SQL_TEXT
--------------------------------------------------------------------------------
00000003E6C69250 1010443947            0
select count(*) from t lookup_me  where i = :dd

00000003E6C69250 1010443947            1
select count(*) from t lookup_me  where i = :dd

可以看到v$sql 里有两条记录是关于刚才的查询对象的。
SQL> select sql_text, VERSION_COUNT, USERS_OPENING, ADDRESS, HASH_VALUE
  2  from v$sqlarea 
  where upper(sql_text)
  like
  'SELECT % T LOOKUP_ME %';  3    4    5 

SQL_TEXT
--------------------------------------------------------------------------------
VERSION_COUNT USERS_OPENING ADDRESS          HASH_VALUE
------------- ------------- ---------------- ----------
select count(*) from t lookup_me  where i = :dd
            2           2.5 00000003E6C69250 1010443947

而在v$sqlarea中只有一条记录。


3、因v$sql及v$sqlarea存放着统计信息在调优时使用居多,但其sql是不全的,如果想获得完整的sql就要用v$sqltext了。

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/40239/viewspace-558328/,如需转载,请注明出处,否则将追究法律责任。

下一篇: 关于回表
请登录后发表评论 登录
全部评论

注册时间:2008-03-10

  • 博文量
    125
  • 访问量
    573592