Oracle v$sql,v$sqlarea,v$sqltext区别

v$sqltext中有内存中完整的sql语句(SQL被分割为多行存储),而其他两个视图都是部分sql语句。但v$sqltext中存储的比较简单,没有该语句的统计信息,比如执行次数等。

v$sqltext 的字段如下:

ADDRESS RAW(4 | 8) Used with HASH_VALUE to uniquely identify a cached cursor

HASH_VALUE NUMBER Used with ADDRESS to uniquely identify a cached cursor

SQL_ID VARCHAR2(13) SQL identifier of a cached cursor

COMMAND_TYPE NUMBER Code for the type of SQL statement (SELECT, INSERT, and so on)

PIECE NUMBER Number used to order the pieces of SQL text

SQL_TEXT VARCHAR2(64) A column containing one piece of the SQL text

其中piece表示SQL语句分片之后的顺序编号,比如三行的值为0,1,2, 按照顺序连接起来就是一个完成的SQL语句。

sql_text 表示分片后的sql语句的一部分,注意它的长度只有64 bytes . 字段HASH_VALUE 和 address 一起唯一标志一条sql 。

v$sql : 存储的是具体的SQL 和执行计划相关信息。

v$sqlarea : 存储SQL语句的前1000个bytes和一些相关的统计信息,比如累计的执行次数,逻辑读,物理读等统计信息

V$SQLAREA 在Oracle9i, Oracle10.1 和Oracle10.2 版本中字段定义都不太一样,Oracle10.2 中会多出sql_fulltext字段,

是一个CLOB字段。

实际上,v$sqlarea 可以看做 v$sql 根据 sqltext 等 做了 group by 之后的信息 。

--------------------------------------------------------------------------------------------------------------

1、可以通过以下语句查一下这些视图的定义,可以看出v$sql及v$sqlarea的源表比较接近 。

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';

SELECT view_definition FROM v$fixed_view_definition WHERE view_name='GV$SQLTEXT';

-- V$SQL 在Oracle10.2.0.4 中的定义:

select inst_id,kglnaobj,kglfnobj,kglobt03, kglobhs0+kglobhs1+kglobhs2+kglobhs3+kglobhs4+kglobhs5+kglobhs6+kglobt16,

kglobt08+kglobt11, kglobt10, kglobt01, decode(kglobhs6,0,0,1), decode(kglhdlmd,0,0,1), kglhdlkc, kglobt04, kglobt05,

kglobt48, kglobt35, kglobpc6, kglhdldc, substr(to_char(kglnatim,'YYYY-MM-DD/HH24:MI:SS'),1,19), kglhdivc, kglobt12,

kglobt13, kglobwdw, kglobt14, kglobwap, kglobwcc, kglobwcl, kglobwui, kglobt42, kglobt43, kglobt15, kglobt02,

decode(kglobt32, 0, 'NONE', 1, 'ALL_ROWS', 2, 'FIRST_ROWS', 3, 'RULE', 4, 'CHOOSE',

'UNKNOWN'), kglobtn0, kglobcce, kglobcceh, kglobt17, kglobt18, kglobts4, kglhdkmk, kglhdpar, kglobtp0, kglnahsh, kglobt46,

kglobt30, kglobt09, kglobts5, kglobt48, kglobts0, kglobt19, kglobts1, kglobt20, kglobt21, kglobts2, kglobt06, kglobt07,

decode(kglobt28, 0, to_number(NULL), kglobt28), kglhdadr, kglobt29, decode(bitand(kglobt00,64),64, 'Y', 'N'),

decode(kglobsta, 1, 'VALID', 2, 'VALID_AUTH_ERROR',3, 'VALID_COMPILE_ERROR', 4,

'VALID_UNAUTH', 5, 'INVALID_UNAUTH', 6, 'INVALID'), kglobt31, substr(to_char(kglobtt0,'YYYY-MM-DD/HH24:MI:SS'),1,19),

decode(kglobt33, 1, 'Y', 'N'), kglhdclt, kglobts3, kglobt44, kglobt45, kglobt47, kglobt49, kglobcla, kglobcbca, kglobt22

from x$kglcursor_child

--V$SQLAREA 在Oracle10.2.0.4 中的定义:

select inst_id, kglnaobj, kglfnobj, kglobt03, kglobhs0+kglobhs1+kglobhs2+kglobhs3+kglobhs4+kglobhs5+kglobhs6, kglobt08+kglobt11,

kglobt10, kglobt01, kglobccc, kglobclc, kglhdlmd, kglhdlkc, kglobt04, kglobt05, kglobt48, kglobt35, kglobpc6, kglhdldc,

substr(to_char(kglnatim,'YYYY-MM-DD/HH24:MI:SS'),1,19), kglhdivc, kglobt12, kglobt13, kglobwdw, kglobt14, kglobwap,

kglobwcc, kglobwcl, kglobwui, kglobt42, kglobt43, kglobt15, kglobt02, decode(kglobt32, 0, 'NONE',1, 'ALL_ROWS', 2, 'FIRST_ROWS',

3, 'RULE', 4, 'CHOOSE', 'UNKNOWN'), kglobtn0, kglobcce, kglobcceh, kglobt17, kglobt18, kglobts4, kglhdkmk, kglhdpar, kglnahsh,

kglobt46, kglobt30, kglobts0, kglobt19, kglobts1, kglobt20, kglobt21, kglobts2, kglobt06, kglobt07,

decode(kglobt28, 0, NULL, kglobt28), kglhdadr, decode(bitand(kglobt00,64),64, 'Y', 'N'),

decode(kglobsta,1, 'VALID', 2, 'VALID_AUTH_ERROR',3, 'VALID_COMPILE_ERROR', 4, 'VALID_UNAUTH', 5, 'INVALID_UNAUTH',6, 'INVALID'),

kglobt31, kglobtt0, decode(kglobt33, 1, 'Y', 'N'), kglhdclt, kglobts3, kglobt44, kglobt45, kglobt47, kglobt49, kglobcla,

kglobcbca, kglobt22

from x$kglcursor_child_sqlid

where kglobt02 != 0

--V$SQLTEXT 在Oracle10.2.0.4 中的定义:

select inst_id,kglhdadr, kglnahsh, kglnasqlid, kgloboct, piece, name

from x$kglna

where kgloboct != 0

2、v$sql与v$sqlarea的区别与联系 :

a、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一个汇总

(相同语句只有一行记录,但是version_count记录了次数)。

b、实际调优中建议使用v$sql, 相对来说比v$sqlarea快,而且还不会产生share pool latch的争用。

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