数据库内部对象X$统计信息过旧,导致v$lock查询慢

前段时间用python写了个zabbix监控脚本,里面有一个检查锁的sql语句,sql语句是这样子的
select count(*) retvalue from v$lock where type in('TM', 'TX') and ctime > 600;
但是zabbix界面显示这条语句超时,zabbix超时时间默认是3s,我将其改为15s,竟然还是超时,看样子要仔细研究这个sql语句了。
这一看不得了,这条语句执行用了18s,统计v$lock的行数竟然要7min之久,这明显无法接受。

SQL> select count(*) retvalue from v$lock where type in('TM', 'TX') and ctime > 600;

  RETVALUE
----------
0 Elapsed: 00:00:18.82

查看其执行计划

SQL> select * from table(dbms_xplan.display_cursor());

---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 1 (100)|
| 1 | SORT AGGREGATE | | 1 | 53 | |
|* 2 | HASH JOIN | | 1 | 53 | 0 (0)|
| | MERGE JOIN CARTESIAN | | | | ()|
|* 4 | FIXED TABLE FULL | X$KSUSE | 1 | 19 | 0 (0)|
| 5 | BUFFER SORT | | 1 | 22 | 0 (0)|
|* 6 | FIXED TABLE FULL | X$KSQRS | 1 | 22 | 0 (0)|
| 7 | VIEW | GV$_LOCK | 10 | 120 | 0 (0)|
| 8 | UNION-ALL | | | | |
|* 9 | FILTER | | | | |
| 10 | VIEW | GV$_LOCK1 | 2 | 24 | 0 (0)|
| 11 | UNION-ALL | | | | |
|* 12 | FIXED TABLE FULL| X$KDNSSF | 1 | 77 | 0 (0)|
|* 13 | FIXED TABLE FULL| X$KSQEQ | 1 | 77 | 0 (0)|
|* 14 | FIXED TABLE FULL | X$KTADM | 1 | 77 | 0 (0)|
|* 15 | FIXED TABLE FULL | X$KTATRFIL | 1 | 77 | 0 (0)|
|* 16 | FIXED TABLE FULL | X$KTATRFSL | 1 | 77 | 0 (0)|
|* 17 | FIXED TABLE FULL | X$KTATL | 1 | 77 | 0 (0)|
|* 18 | FIXED TABLE FULL | X$KTSTUSC | 1 | 77 | 0 (0)|
|* 19 | FIXED TABLE FULL | X$KTSTUSS | 1 | 77 | 0 (0)|
|* 20 | FIXED TABLE FULL | X$KTSTUSG | 1 | 77 | 0 (0)|
|* 21 | FIXED TABLE FULL | X$KTCXB | 1 | 77 | 0 (0)|
--------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 2 - access("SADDR"="S"."ADDR" AND
TO_CHAR(USERENV('INSTANCE'))||RAWTOHEX("RADDR")=TO_CHAR("R"."INST_ID")||
RAWTOHEX("R"."ADDR"))
4 - filter("S"."INST_ID"=USERENV('INSTANCE'))
6 - filter(("R"."KSQRSIDT"='TM' OR "R"."KSQRSIDT"='TX'))
9 - filter(USERENV('INSTANCE') IS NOT NULL)

统计v$lock的行数

SQL> select count(*) from v$lock;

  COUNT(*)
----------
600 Elapsed: 00:07:46.84

这条语句的执行计划与上面的一样,这里我就不贴出来了

v$lock只有600行,怎么会执行时间这么久,通过v$session能看到这条语句的等待事件为"direct path read temp"
该等待事件表示服务器进程直接读取临时表空间的数据,通常由临时表太大造成。从上面的执行计划中可以看出临时表很大的原因可能是"MERGE JOIN CARTESIAN"。
"MERGE JOIN CARTESIAN"表示笛卡尔联接,如果两表的行数都不小的话,这的确会造成临时表过大。查看X$KSUSE,X$KSQRS的行数

SQL> select count(*) from X$KSUSE;                                                  

  COUNT(*)
----------
4544 SQL> select count(*) from X$KSQRS; COUNT(*)
----------
20224

这几千和几万来个笛卡尔积就是几千万的临时数据了,而我的pga只有4g,pga不够所以就用到了临时表空间进行表关联,也就造成了等待事件,所以说这条语句慢的主因就是这个笛卡儿积。

这条语句之前执行都好好的,为什么现在慢了呢,最可能的情况是统计信息过旧,因为自动统计信息收集job不会收集固定对象也就是X$表的统计信息。

收集下固定对象的统计信息

SQL> begin
dbms_stats.gather_fixed_objects_stats;
end;
/ PL/SQL procedure successfully completed.

再执行以下语句,可以看到执行时间0.1s都不到,而且执行计划也恢复正常,赶紧在我这边的生产库把类似问题进行处理,嘿嘿。

SQL> select count(*) from v$lock;

  COUNT(*)
----------
600 Elapsed: 00:00:00.08 SQL> select * from table(dbms_xplan.display_cursor()); ---------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 29 (100)| |
| 1 | SORT AGGREGATE | | 1 | 36 | | |
| 2 | HASH JOIN | | 3034 | 106K| 29 (100)| 00:00:01 |
| 3 | HASH JOIN | | 15 | 360 | 23 (100)| 00:00:01 |
| 4 | VIEW | GV$_LOCK | 15 | 180 | 22 (100)| 00:00:01 |
| 5 | UNION-ALL | | | | | |
| 6 | FILTER | | | | | |
| 7 | VIEW | GV$_LOCK1 | 7 | 84 | 15 (100)| 00:00:01 |
| 8 | UNION-ALL | | | | | |
| 9 | FIXED TABLE FULL| X$KDNSSF | 1 | 16 | 1 (100)| 00:00:01 |
| 10 | FIXED TABLE FULL| X$KSQEQ | 6 | 102 | 14 (100)| 00:00:01 |
| 11 | FIXED TABLE FULL | X$KTADM | 1 | 20 | 5 (100)| 00:00:01 |
| 12 | FIXED TABLE FULL | X$KTATRFIL | 1 | 14 | 0 (0)| |
| 13 | FIXED TABLE FULL | X$KTATRFSL | 1 | 14 | 0 (0)| |
| 14 | FIXED TABLE FULL | X$KTATL | 1 | 20 | 0 (0)| |
| 15 | FIXED TABLE FULL | X$KTSTUSC | 1 | 14 | 0 (0)| |
| 16 | FIXED TABLE FULL | X$KTSTUSS | 1 | 16 | 0 (0)| |
| 17 | FIXED TABLE FULL | X$KTSTUSG | 1 | 14 | 0 (0)| |
| 18 | FIXED TABLE FULL | X$KTCXB | 1 | 18 | 1 (100)| 00:00:01 |
| 19 | FIXED TABLE FULL | X$KSUSE | 4544 | 54528 | 1 (100)| 00:00:01 |
| 20 | FIXED TABLE FULL | X$KSQRS | 20224 | 237K| 5 (100)| 00:00:01 |
---------------------------------------------------------------------------------------

总结:
1.一些动态性能视图v$查询很慢的话,可能是由于动态性能视图所查询的内部对象表x$统计信息过旧,cbo选择了错误的执行计划造成。
2.自动统计信息收集job不会收集内部对象表的统计信息,所以需要dba定时手工收集,或者是自己创建个job定期执行。

Oracle - v$lock查询慢原因分析的更多相关文章

  1. Oracle spatial空间查询的选择度分析

    在上一篇中,我用一个案例演示了对于数值或字符串类型的字段,选择度的计算方法.并证明了当字段值的选择度不同时,将会影响CBO选择最终的执行计划.对于可排序的字段类型,选择度计算模型已经有很多人写博客介绍 ...

  2. mysql服务器查询慢原因分析方法

    mysql数据库在查询的时候会出现查询结果很慢,超过1秒,项目中需要找出执行慢的sql进行优化,应该怎么找呢,mysql数据库提供了一个很好的方法,如下: mysql5.0以上的版本可以支持将执行比较 ...

  3. ORACLE 查询不走索引的原因分析,解决办法通过强制索引或动态执行SQL语句提高查询速度

    (一)索引失效的原因分析: <>或者单独的>,<,(有时会用到,有时不会) 有时间范围查询:oracle 时间条件值范围越大就不走索引 like "%_" ...

  4. oracle分页查询及原理分析(总结)

    oracle分页查询及原理分析(总结) oracle分页查询是开发总为常用的语句之一,一般情况下公司框架会提供只需套用,对于增删改查而言,查是其中最为关键也是最为难的一块,其中就有使用率最高的分页查询 ...

  5. Oracle包被锁定的原因分析及解决方案

    http://blog.csdn.net/jojo52013145/article/details/7470812 在数据库的开发过程中,经常碰到包.存储过程.函数无法编译或编译时会导致PL/SQL ...

  6. ORACLE中order by造成分页不正确原因分析

     工作中遇到的问题: 为调用方提供一个分页接口时,调用方一直反应有部分数据取不到,且取到的数据有重复的内容,于是我按以下步骤排查了下错误. 1.检查分页页码生成规则是否正确. 2.检查SQL语句是否正 ...

  7. oracle 11g导出少了空表,原因分析

    oracle 11g导出少了空表 使用exp命令的时候,会出现少表的情况,是因为在11g版本中如果一个表里面是空的,为了节省空间,默认是不会给这个表分配空间的,在导出的时候也就不会将空表导出的,自然导 ...

  8. SQL查询速度慢的原因分析和解决方案

    SQL查询速度慢的原因分析和解决方案 查询速度慢的原因很多,常见如下几种: 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) 2.I/O吞吐量小,形成了瓶颈效应. 3.没有创建 ...

  9. sql 查询慢的48个原因分析

      sql 查询慢的48个原因分析. server memory 服务器配置选项配置为物理内存的 1.5 倍(虚拟内存大小设置的一半). 字句同时执行,SQL SERVER根据系统的负载情况决定最优的 ...

随机推荐

  1. 关于定义序列化器时,read_only和write_only有什么作用

    关于序列化和反序列化 ​ 在谈论前,先说一下序列化和反序列化,这两个概念最初是在学习json的时候提出来的,回头来看,其实可以用最初的理解就可以了 序列化就是将对象转化方便传输和存储字节序列,例如js ...

  2. 【Linux命令】磁盘分区,格式化,挂载命令,创建交换分区(fdisk,mkfs,mount,umount)

    友情链接 磁盘分区,格式化,挂载,创建交换分区:https://www.cnblogs.com/HeiDi-BoKe/p/11936998.html RAID工作级别:https://www.cnbl ...

  3. npm报错及解决

    nodejs安装之后 无法使用 npm的解决方法 首先我们要知道Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境 Node.js 使用了一个事件驱动.非阻塞式 I ...

  4. Linux系统文件属性知识

    ---------------------------------------------------------------------------------------------------- ...

  5. Java题库——Chapter13抽象类和接口

    )What is the output of running class Test? public class Test { public static void main(String[ ] arg ...

  6. ASP.NET Core 2.2 WebApi 系列【七】泛型仓储模式和工作单元

    在之前的泛型仓储模式实现中,每个增删改都调用了SaveChanges方法,导致每次更新都提交了事务. 在实际开发过程中,我们经常遇到同时操作多张表数据,那么按照之前的写法,对数据库提交了多次操作,开启 ...

  7. javaWeb核心技术第八篇之Cookie和Session

    会话技术: 会话是什么? 浏览器和服务器交互,浏览器打开网页访问服务器,会话开始,正常交互. 浏览器关闭,会话结束. 会话能干什么? 会话可以共享数据. Cookie和session将数据保存在不同的 ...

  8. 简约清新日系你好五月通用PPT模板推荐

    模版来源:http://ppt.dede58.com/peixunyanjiang/26488.html

  9. opencv-python 图像基础处理(四)

    图像梯度-Sobel算子 Gx等于左边减去右边    Gy等于下减去上 可以得到像素值 dst = cv2.Sobel(src, ddepth, dx, dy, ksize)- ddepth:图像的深 ...

  10. 解决brew update很慢

    一般遇到这种问题,就跟墙有关啦,需要更换源. 用清华的源就非常好,去清华镜像的官网看一下说明,https://mirrors.tuna.tsinghua.edu.cn/help/homebrew/ $ ...