[20150803]无法通过sql_id找到sql语句3.txt

本文探讨了在Oracle数据库中使用SQL_ID进行SQL语句查询时遇到的问题,包括共享池大小限制及执行错误等情况,并通过实际案例展示了如何定位这些难以捉摸的问题。

[20150803]无法通过sql_id找到sql语句3.txt

--前一阵子,在做优化时遇到1个无法通过sql_id找到sql语句的情况:
http://blog.itpub.net/267265/viewspace-1749265/

--就是因为共享池太小,执行次数少,没到取样时间,已经从共享池清除。

--今天自己google,想想看看还有那种情况会出现呢?如果1条语句执行错误,会记录sql_id,当时查询v$sql视图应该也不能找到。
--自己直接那生产系统看看:

1.建立测试环境:
--看看生产系统的情况:
SYS@xxxxxx:1521/dbcn> @ver1
PORT_STRING                    VERSION        BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx            11.2.0.4.0     Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

SELECT COUNT (*), sql_id
    FROM V$ACTIVE_SESSION_HISTORY
   WHERE event = 'SQL*Net break/reset to client'
GROUP BY sql_id having count(*)>=9
ORDER BY 1 DESC;

  COUNT(*) SQL_ID
---------- -------------
       369 cm0qrtprj32qv
         9 c21vhszr9gbdq

SYSTEM@xxxxxx:1521/dbcn> @dpc cm0qrtprj32qv ''
PLAN_TABLE_OUTPUT
-----------------------------------------------------------
SQL_ID: cm0qrtprj32qv cannot be found
--无法发现sql语句。

SYS@192.168.99.106:1521/dbcn> select * from v$sql where sql_id='cm0qrtprj32qv';
no rows selected

--查询x$kglob视图:
$ cat shp4.sql
SELECT DECODE (kglhdadr,
               kglhdpar, '父游标句柄地址',
               '子游标句柄地址')
          text,
       kglhdadr,
       kglhdpar,
       substr(kglnaobj,1,20),
       kglobhd0,
       kglobhd6,
       kglobhs0,kglobhs6,kglobt16,
       kglobhs0+kglobhs6+kglobt16,
           kglobhs0+kglobhs1+kglobhs2+kglobhs3+kglobhs4+kglobhs5+kglobhs6+kglobt16 N20
  FROM x$kglob
WHERE kglobt03 = '&1';


SYS@192.168.99.106:1521/dbcn> @sharepool/shp4 cm0qrtprj32qv
old  14:  WHERE kglobt03 = '&1'
new  14:  WHERE kglobt03 = 'cm0qrtprj32qv'

TEXT           KGLHDADR         KGLHDPAR         SUBSTR(KGLNAOBJ,1,20)                    KGLOBHD0         KGLOBHD6           KGLOBHS0   KGLOBHS6   KGLOBT16 KGLOBHS0+KGLOBHS6+KGLOBT16        N20
-------------- ---------------- ---------------- ---------------------------------------- ---------------- ---------------- ---------- ---------- ---------- -------------------------- ----------
子游标句柄地址 000000130BCC8228 0000001309E41A28 SELECT PBD_FHGT,PBD_                     00               00                        0          0       4091                       4091       4091
子游标句柄地址 000000130570E978 0000001309E41A28 SELECT PBD_FHGT,PBD_                     00               00                        0          0       4091                       4091       4091
父游标句柄地址 0000001309E41A28 0000001309E41A28 SELECT PBD_FHGT,PBD_                     0000001307FF9158 00                     4976          0          0                       4976       4976

--
SYS@192.168.99.106:1521/dbcn> SELECT distinct kglnaobj c100 from x$kglob where  kglobt03 = 'cm0qrtprj32qv';
C100
----------------------------------------------------------------------------------------------------
SELECT PBD_FHGT,PBD_FWGT,PBD_FITL,PBD_FUNL,PBD_FCHR,PBD_FPTC,PBD_FFCE,PBH_FHGT,PBH_FWGT,PBH_FITL,PBH
_FUNL,PBH_FCHR,PBH_FPTC,PBH_FFCE,PBL_FHGT,PBL_FWGT,PBL_FITL,PBL_FUNL,PBL_FCHR,PBL_FPTC,PBL_FFCE,PBT_
CMNT  FROM SYSTEM.PBCATTBL   WHERE PBT_OWNR = :"SYS_B_0" AND PBT_TNAM = :"SYS_B_1"

--这个是pb的程序,而这个表再我们的系统不存在。
SYS@192.168.99.106:1521/dbcn> @desc SYSTEM.PBCATTBL
ERROR:
ORA-04043: object SYSTEM.PBCATTBL does not exist

--导致每次程序访问是报错。

select trunc(sample_time,'hh24'),sql_id,count(*) from V$ACTIVE_SESSION_HISTORY where sql_id='cm0qrtprj32qv' and sample_time>=trunc(sysdate)+8/24
group by trunc(sample_time,'hh24'),sql_id
order by trunc(sample_time,'hh24') desc ,sql_id;

TRUNC(SAMPLE_TIME,' SQL_ID          COUNT(*)
------------------- ------------- ----------
2015-08-03 10:00:00 cm0qrtprj32qv         28
2015-08-03 09:00:00 cm0qrtprj32qv         94
2015-08-03 08:00:00 cm0qrtprj32qv         60

--当前我执行的时间是10:23,看看9-10点,这个错误就浪费了94秒时间。可以发现执行实在太频繁。


--接着看看另外1条语句:

SYS@xxxxxx:1521/dbcn> SELECT distinct kglnaobj c100 from x$kglob where  kglobt03 = 'c21vhszr9gbdq';
C100
----------------------------------------------------------------------------------------------------
Select csz2 From gy_xtcs where xtxh =:"SYS_B_0" And csmc =:"SYS_B_1"

SYS@xxxxxx:1521/dbcn> @desc portal_his.GY_XTCS
Name   Null?    Type
------ -------- ----------------------------
CSMC   NOT NULL VARCHAR2(40)
CSZ             VARCHAR2(200)
MRZ             VARCHAR2(100)
BZ              VARCHAR2(80)

--根本没有xtxh字段。
--真不知道这种大量无法执行的命令对性能能产生多大的影响。不过都可以通过x$kglob查询到。

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

转载于:http://blog.itpub.net/267265/viewspace-1760158/

<think>我们想要合并会话信息和对应的SQL语句,以便分析临时表空间的使用情况。在Oracle中,可以通过关联`v$session`、`v$tempseg_usage`和`v$sql`等动态性能视图来实现。 目标:显示每个会话的临时表空间使用情况,并关联到该会话正在执行的SQL语句。 步骤: 1. 从`v$tempseg_usage`视图中获取临时段的使用情况(包括会话地址、SQL_ID、使用的块数等)。 2. 关联`v$session`视图,通过会话地址(session_addr)或会话ID(sid)来获取会话的详细信息(如用户名、机器名、程序名等)。 3. 关联`v$sql`视图,通过SQL_ID来获取具体的SQL文本。 注意:一个会话可能执行多个SQL语句,而`v$tempseg_usage`会记录每个SQL语句使用的临时段。因此,我们通过SQL_ID关联到具体的SQL语句。 以下是一个查询示例,它将会话信息、临时表空间使用情况以及对应的SQL语句合并显示: ```sql SELECT s.sid, s.serial#, s.username, s.machine, s.program, s.status, s.logon_time, t.tablespace, t.contents, t.segtype, ROUND((t.blocks * p.value)/1024/1024, 2) AS temp_used_mb, t.sql_id, q.sql_text FROM v$tempseg_usage t JOIN v$session s ON t.session_addr = s.saddr JOIN v$sql q ON t.sql_id = q.sql_id CROSS JOIN v$parameter p WHERE p.name = &#39;db_block_size&#39; AND t.blocks > 0; -- 只显示正在使用临时空间的 ``` 解释: - `v$tempseg_usage`:记录临时段的使用情况,包括会话地址(session_addr)、SQL_ID、使用的块数(blocks)、表空间名(tablespace)等。 - `v$session`:提供会话的详细信息,我们通过`session_addr`关联。 - `v$sql`:通过SQL_ID关联,获取SQL文本。 - `v$parameter`:用于获取数据库块大小(db_block_size),因为临时段使用的块数需要乘以块大小才能转换为字节(这里再转换为MB)。 注意:`v$tempseg_usage`中的blocks是使用临时表空间的块数,乘以块大小(db_block_size)得到字节数,再除以1024两次得到MB。 这个查询可以显示每个会话的临时表空间使用量(MB),并显示对应的SQL语句,方便我们分析是哪些SQL语句占用了大量的临时空间。 另外,由于一个会话可能同时执行多个SQL语句(每个SQL语句可能有多个临时段),所以一个会话可能会对应多行。 如果临时表空间使用过大,我们可以通过这个查询定位到具体的会话和SQL语句,然后进一步优化SQL或终止会话。 注意:在生产环境中执行此类查询时,要注意其性能影响,因为关联多个视图可能有一定的开销。 根据引用[2]中提到的,我们还可以通过其他方式监控临时表空间,但上述查询提供了会话和SQL级别的详细信息。 引用[1]提到临时表空间用于排序、哈希连接等操作,因此这些操作较多的SQL语句可能会占用大量临时空间。 引用[3][4][5]提到临时表的使用,在Oracle中,全局临时表(GTT)的数据存储在临时表空间中,所以如果会话中使用了临时表并且数据量较大,也会在临时表空间中占用空间。 如果查询结果中SQL_TEXT显示的是PL/SQL匿名块(如DECLARE BEGIN END),则可能是PL/SQL块中使用了临时表或执行了排序操作。 通过这个查询,我们可以监控当前数据库中哪些会话和SQL正在大量使用临时表空间,从而进行优化或管理。 相关问题: 1. 如何终止占用大量临时表空间的会话? 2. 如何优化使用大量临时表空间的SQL语句3. 临时表空间的使用与哪些数据库操作有关? 4. 如何监控临时表空间的历史使用情况?</think>要合并显示会话信息和对应的 SQL 语句以分析临时表空间使用情况,可通过以下 SQL 查询实现。该查询关联 Oracle 的关键动态性能视图,提供全面的分析视角: ```sql SELECT s.sid AS "会话ID", s.serial# AS "序列号", s.username AS "用户名", s.program AS "客户端程序", s.status AS "会话状态", t.tablespace AS "临时表空间", ROUND((t.blocks * p.value)/1024/1024, 2) AS "已用空间(MB)", t.sql_id AS "SQL_ID", q.sql_text AS "完整SQL语句", t.segtype AS "段类型" FROM v$session s JOIN v$tempseg_usage t ON s.saddr = t.session_addr JOIN v$sql q ON t.sql_id = q.sql_id CROSS JOIN v$parameter p WHERE p.name = &#39;db_block_size&#39; AND t.blocks > 0 -- 只显示正在使用临时空间的会话 ORDER BY "已用空间(MB)" DESC; ``` ### 关键视图说明: 1. **`v$session`** 提供会话基础信息(SID, Serial#, 用户名等)[^2] 2. **`v$tempseg_usage`** 核心临时空间使用视图,包含: - `blocks`:已用数据块数量 - `tablespace`:临时表空间名 - `sql_id`:关联的 SQL 语句 ID - `segtype`:段类型(SORT/HASH/JOIN 等)[^1] 3. **`v$sql`** 通过 `sql_id` 关联获取完整 SQL 文本 4. **`v$parameter`** 获取 `db_block_size` 计算实际空间用量: $$ \text{实际空间(MB)} = \frac{\text{blocks} \times \text{db\_block\_size}}{1024 \times 1024} $$ ### 输出列说明: | 列名 | 说明 | 分析价值 | |------|------|----------| | 会话ID | 会话唯一标识 | 定位问题会话 | | 已用空间(MB) | 精确空间消耗 | 识别资源消耗TOP会话 | | SQL语句 | 完整SQL文本 | 分析SQL是否可优化 | | 段类型 | 操作类型(SORT/HASH等) | 判断优化方向[^1] | | 客户端程序 | 发起程序名(如JDBC) | 追踪应用来源 | ### 典型分析场景: 1. **定位高消耗SQL** ```sql -- 查找消耗超过100MB的排序操作 SELECT * FROM ( SELECT /*+ 嵌套子查询示例 */ ... ) -- 显示为SORT段类型且高空间消耗[^3] ``` 2. **识别异常会话** ```sql -- 状态为INACTIVE但仍占用临时空间 WHERE s.status = &#39;INACTIVE&#39; AND t.blocks > 1000 ``` 3. **关联临时表操作** ```sql -- 创建会话级临时表(空间持续占用) CREATE GLOBAL TEMPORARY TABLE ... ON COMMIT PRESERVE ROWS; -- 显示为DATA段类型[^5] ``` ### 优化建议: 1. 定期运行此查询并保存结果到历史表 2. 对高频出现的SQL进行执行计划分析 3. 对使用`ON COMMIT PRESERVE ROWS`的临时表评估是否可改为事务级[^5] 4. 对排序/分组操作考虑增加索引优化 > 通过此关联分析,可精准定位临时表空间异常占用的源头,结合SQL优化或会话管理解决问题[^1][^2]。 --- **相关问题:** 1. 如何自动监控Oracle临时表空间的异常增长? 2. 哪些类型的SQL语句最容易导致临时表空间膨胀? 3. 临时表空间使用与PGA内存管理有何关联? 4. 如何区分临时表空间中排序段和临时表段的存储差异?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值