数据库内部对象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. [洛谷P1169][题解][ZJOI2007]午餐

    这是题目吗? 显然的DP,讲几个重要的地方 1.贪心:让吃饭时间长的先排队(证明从略) 2.状态: f[i][j][k]代表前i个人,一号时间j,二号时间k显然MLE 所以压缩成f[i][j]代表前i ...

  2. BZOJ3894/LG4313 文理分科 新建点最小割

    问题描述 BZOJ3894 LG4313 题解 显然一个人只能选文/理 -> 一个人只能属于文(S).理(T)集合中的一个 可以把选择文得到 \(art\) 的收益看做选择文失去 \(scien ...

  3. P3747 [六省联考2017]相逢是问候

    题意 如果对一个数操作\(k\)次,那么这个数会变成\(c^{c^{...^{a_i}}}\),其中\(c\)有\(k\)个. 根据P4139 上帝与集合的正确用法这道题,我们可以知道一个数不断变为自 ...

  4. dotnet core 调用electron来开发UI的探索

    先上仓库地址 https://github.com/lightszero/webwindow.netcore dotnet core 很喜欢,问题dotnet core 不包含GUI,经过一些尝试,觉 ...

  5. [译]Vulkan教程(29)组合的Image采样器

    [译]Vulkan教程(29)组合的Image采样器 Combined image sampler 组合的image采样器 Introduction 入门 We looked at descripto ...

  6. strlen函数 (求字符串长度函数)

    strlen函数原型在<string.h>中 #include <stdio.h> #include <string.h> int main(){ char *p= ...

  7. eclipse的一些常用快捷键

    掌握了eclipse快捷键功能,能够大大提高开发效率. 这里总结一些eclipse的常用快捷键. 编辑相关快捷键  1. [ALT+/]:此快捷键为用户编辑的好帮手,能为用户提供内容的辅助,不要为记不 ...

  8. 浅谈Httpmodules

    HttpModule是ASP.NET过滤器,可以理解为HTTP请求的必经之地我们只要实现IHttpModule接口,就可以取代HttpModule namespace BookShop.Handler ...

  9. 02-java性能调优-JVM内存模型详解

    JVM整体结构与内存模型之间的关系 JVM整体结构图如下: 先贴一个代码: package com.jvm.jvmCourse2; public class Math { public static ...

  10. docker中安装宝塔面板

    我的电脑是win10,安装的virtualbox其上装的ubutun14,ubutun也安装了docker,今天我补充一个完整的操作流程.怎么在docker中安装宝塔面板?先打个岔,这些命令总是记不住 ...