CPU语句占用高解决一例

  查看主机CPU,发现只有10%的IDLE,高CPU进程的语句的基本为11个地区全扫描,存大较多的latch:cache buffers chains. 通过查看报告,发现这条语句1小时执行超过10万次,

SELECT   ps_id, action_id, ps_param, TO_CHAR (busi_code), TO_CHAR (stop_type),

         TO_CHAR (done_code), TO_CHAR (ps_type), TO_CHAR (prio_level),

         TO_CHAR (sort_id), TO_CHAR (sub_valid_date, 'yyyymmddhh24miss'),

         TO_CHAR (ps_service_type), bill_id, sub_bill_id,

         TO_CHAR (create_date, 'yyyymmddhh24miss'), TO_CHAR (retry_times),

         TO_CHAR (fail_num), fail_reason, TO_CHAR (op_id), TO_CHAR (sp_id),

         region_code, TO_CHAR (org_id), TO_CHAR (old_ps_id), ps_net_code,

         old_ps_param, target_param

    FROM ps_pro_split4

   WHERE ps_status = 0 AND ps_net_code = :f1

ORDER BY dead_line, prio_level DESC;

 

select  ps_status , ps_net_code,count(*) from  ps_pro_split4 group by   ps_status, ps_net_code order by count(*) desc;

 

PS_STATUS

PS_NET_CODE

COUNT(*)

0

GCSTATUS

35140

1

GCSTATUS

4000

1

SJB

43

1

LYH

16

0

CPSTATUS

3

0

SPMS

3

1

LSRX

3

1

VAC

3

1

NB6_HW

2

0

ZXWG

2

1

HYS

2

1

ZXWG

2

9

NB6_HW

1

 

 

与这个应用的开发交流后得知 每个对于上面的查询的每一列为条件查询次数基本相同,如果在这两个字段(PS_STATUSPS_NET_CODE建上联合索引的话,可以加快以下的查询:

1

SJB

43

1

LYH

16

0

CPSTATUS

3

0

SPMS

3

1

LSRX

3

1

VAC

3

1

NB6_HW

2

0

ZXWG

2

1

HYS

2

1

ZXWG

2

9

NB6_HW

 

 

 

但目前主要积压在GCSTATUS

的处理上,对于GCSTATUS来说使用表扫描效最高,目前由于ps_net_code 这个条件上用的在绑定变量,在SQL parsebind peeking容易造成执行计划变化,建议这个字段不用绑定变量,并在两个字段建一个联合索引,让这个功能的语句每次执行时,进行一次hard parse会做一次bind peeking,可以避免发生SQL执行计划变化。

 

这个问题关建在于,这个表ps_pro_split4ps_status ps_net_code  字段倾斜太历害,牵扯到bind peeking导致执行计划改变的问题,让应用开发将下面的语句在GCSTATUS这个功能ps_net_code = :f1改成不用绑定变量

SELECT   ps_id, action_id, ps_param, TO_CHAR (busi_code), TO_CHAR (stop_type),

         TO_CHAR (done_code), TO_CHAR (ps_type), TO_CHAR (prio_level),

         TO_CHAR (sort_id), TO_CHAR (sub_valid_date, 'yyyymmddhh24miss'),

         TO_CHAR (ps_service_type), bill_id, sub_bill_id,

         TO_CHAR (create_date, 'yyyymmddhh24miss'), TO_CHAR (retry_times),

         TO_CHAR (fail_num), fail_reason, TO_CHAR (op_id), TO_CHAR (sp_id),

         region_code, TO_CHAR (org_id), TO_CHAR (old_ps_id), ps_net_code,

         old_ps_param, target_param

    FROM ps_pro_split4

   WHERE ps_status = 0 AND ps_net_code = :f1

ORDER BY dead_line, prio_level DESC;

 

TO

 

SELECT   ps_id, action_id, ps_param, TO_CHAR (busi_code), TO_CHAR (stop_type),

         TO_CHAR (done_code), TO_CHAR (ps_type), TO_CHAR (prio_level),

         TO_CHAR (sort_id), TO_CHAR (sub_valid_date, 'yyyymmddhh24miss'),

         TO_CHAR (ps_service_type), bill_id, sub_bill_id,

         TO_CHAR (create_date, 'yyyymmddhh24miss'), TO_CHAR (retry_times),

         TO_CHAR (fail_num), fail_reason, TO_CHAR (op_id), TO_CHAR (sp_id),

         region_code, TO_CHAR (org_id), TO_CHAR (old_ps_id), ps_net_code,

         old_ps_param, target_param

    FROM ps_pro_split4

   WHERE ps_status = 0 AND ps_net_code = 'GCSTATUS'

ORDER BY dead_line, prio_level DESC;

 

再建上ps_status , ps_net_code这两个字段的联合索引,

 

CREATE INDEX P_ON ps_pro_split4(ps_status , ps_net_code)  online;

 

进行表分析并分析索引列的柱状图,

改完一个地市,发可以看到IDLE CPU回来5%,改完11个地区后CPU IDLE恢复为88%,问题得到解决。

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

转载于:http://blog.itpub.net/10834762/viewspace-589228/

为什么要学JVM1、一切JAVA代码都运行在JVM之上,只有深入理解虚拟机才能写出更强大的代码,解决更深层次的问题。2、JVM是迈向级工程师、架构师的必备技能,也是薪、职位的不二选择。3、同时,JVM又是各大软件公司笔试、面试的重中之重,据统计,头部的30家互利网公司,均将JVM作为笔试面试的内容之一。4、JVM内容庞大、并且复杂难学,通过视频学习是最快速的学习手段。课程介绍本课程包含11个大章节,总计102课时,无论是笔试、面试,还是日常工作,可以让您游刃有余。第1章 基础入门,从JVM是什么开始讲起,理解JDK、JRE、JVM的关系,java的编译流程和执行流程,让您轻松入门。第2章 字节码文件,深入剖析字节码文件的全部组成结构,以及javap和jbe可视化反解析工具的使用。第3章 类的加载、解释、编译,本章节带你深入理解类加载器的分类、范围、双亲委托策略,自己手写类加载器,理解字节码解释器、即时编译器、混合模式、热点代码检测、分层编译等核心知识。第4章 内存模型,本章节涵盖JVM内存模型的全部内容,程序计数器、虚拟机栈、本地方法栈、方法区、永久代、元空间等全部内容。第5章 对象模型,本章节带你深入理解对象的创建过程、内存分配的方法、让你不再稀里糊涂。第6章 GC基础,本章节是垃圾回收的入门章节,带你了解GC回收的标准是什么,什么是可达性分析、安全点、安全区,四种引用类型的使用和区别等等。第7章 GC算法与收集器,本章节是垃圾回收的重点,掌握各种垃圾回收算法,分代收集策略,7种垃圾回收器的原理和使用,垃圾回收器的组合及分代收集等。第8章 GC日志详解,各种垃圾回收器的日志都是不同的,怎么样读懂各种垃圾回收日志就是本章节的内容。第9章 性能监控与故障排除,本章节实战学习jcmd、jmx、jconsul、jvisualvm、JMC、jps、jstatd、jmap、jstack、jinfo、jprofile、jhat总计12种性能监控和故障排查工具的使用。第10章 阿里巴巴Arthas在线诊断工具,这是一个特别小惊喜,教您怎样使用当前最火热的arthas调优工具,在线诊断各种JVM问题。第11章 故障排除,本章会使用实际案例讲解单点故障、并发和垃圾回收导致的CPU的问题,怎样排查和解决它们。课程资料课程附带配套项目源码2个159页清PDF理论篇课件1份89页清PDF实战篇课件1份Unsafe源码PDF课件1份class_stats字段说明PDF文件1份jcmd Thread.print解析说明文件1份JProfiler内存工具说明文件1份字节码可视化解析工具1份GC日志可视化工具1份命令行工具cmder 1份学习方法理论篇部分推荐每天学习2课时,可以在公交地铁上用手机进行学习。实战篇部分推荐对照视频,使用配套源码,一边练习一遍学习。课程内容较多,不要一次性学太多,而是要循序渐进,坚持学习。      
<think>我们正在处理一个数据库性能优化问题,具体是如何查找在特定时间段内CPU占用的SQL语句。根据用户提供的引用信息,我们可以从以下几个方面入手: 1. 在Oracle数据库中,可以通过查询动态性能视图(如V$SQL、V$SESSION、V$ACTIVE_SESSION_HISTORY等)来获取SQL语句的执行统计信息,包括CPU时间。 2. 在MongoDB中,可以通过数据库自带的监控工具(如mongostat、mongotop)或日志分析来识别CPU使用率的操作。 3. 在MySQL中,可以通过慢查询日志或performance_schema来监控SQL语句CPU使用情况。 由于用户没有指定数据库类型,但引用的内容涉及Oracle和MongoDB,这里我们以Oracle为例(因为引用[1]提到的是Oracle相关的视图),同时也会简要提及其他数据库。 ### 步骤一:确定时间范围 首先,我们需要明确要分析的时间段。 ### 步骤二:查询CPU占用的SQL(Oracle) 在Oracle中,可以使用以下查询来查找特定时间段内CPU占用的SQL语句: ```sql SELECT sql_id, sql_text, cpu_time, elapsed_time, executions FROM v$sqlstats WHERE last_active_time BETWEEN TO_DATE('开始时间', 'YYYY-MM-DD HH24:MI:SS') AND TO_DATE('结束时间', 'YYYY-MM-DD HH24:MI:SS') ORDER BY cpu_time DESC; ``` 或者使用ASH(Active Session History)数据,ASH每秒钟采样一次,可以更精确地定位: ```sql SELECT ash.sql_id, s.sql_text, SUM(ash.cpu_time_delta) total_cpu FROM v$active_session_history ash, v$sql s WHERE ash.sql_id = s.sql_id AND ash.sample_time BETWEEN TO_DATE('开始时间', 'YYYY-MM-DD HH24:MI:SS') AND TO_DATE('结束时间', 'YYYY-MM-DD HH24:MI:SS') GROUP BY ash.sql_id, s.sql_text ORDER BY total_cpu DESC; ``` ### 步骤三:分析SQL语句 对于查询出来的CPU占用的SQL,需要进一步分析: - 检查SQL语句是否存在全表扫描、笛卡尔积连接、不必要的复杂计算等。 - 查看执行计划,确定是否缺少索引或者统计信息过时。 - 考虑SQL语句是否可以被优化,例如重写查询、添加索引等。 ### 步骤四:其他数据库 - **MySQL**:可以通过慢查询日志(需要开启并配置`long_query_time`)或者查询`performance_schema`中的事件统计表(如`events_statements_summary_by_digest`)来获取SQL的CPU使用情况。 - **MongoDB**:可以通过数据库分析器(profiler)来记录操作,然后分析记录。或者使用`db.currentOp()`来查看当前正在执行的操作,但历史操作需要依赖日志或监控系统。 ### 注意事项 - 在分析时,注意区分CPU时间和等待时间。CPU时间可能表示计算密集型操作,而等待时间可能表示I/O或锁竞争。 - 如果数据库有AWR(Oracle)或类似的性能报告工具,可以利用这些工具进行更详细的分析。 ### 相关问题 1. 如何优化CPU占用的SQL语句? 2. 除了CPU时间,还有哪些指标可以用来评估SQL语句的性能? 3. 在Oracle中,如何配置AWR报告来诊断性能问题?</think>### 查找特定时间段内CPU占用的SQL语句方法 #### 1. **Oracle数据库** 通过动态性能视图查询历史CPU消耗: ```sql SELECT /*+ 使用ASH历史数据 */ ash.SQL_ID, s.SQL_TEXT, SUM(ash.CPU_TIME_DELTA) AS total_cpu_ms, COUNT(*) AS samples_count FROM DBA_HIST_ACTIVE_SESS_HISTORY ash JOIN DBA_HIST_SQLTEXT s ON ash.SQL_ID = s.SQL_ID WHERE ash.SAMPLE_TIME BETWEEN TO_TIMESTAMP('2023-11-01 14:00:00', 'YYYY-MM-DD HH24:MI:SS') AND TO_TIMESTAMP('2023-11-01 15:00:00', 'YYYY-MM-DD HH24:MI:SS') GROUP BY ash.SQL_ID, s.SQL_TEXT ORDER BY total_cpu_ms DESC FETCH FIRST 10 ROWS ONLY; ``` **关键参数**: - `SAMPLE_TIME`:指定时间段范围 - `CPU_TIME_DELTA`:CPU时间增量(毫秒) - `SQL_TEXT`:完整SQL语句文本 #### 2. **MySQL数据库** 使用Performance Schema分析历史SQL: ```sql SELECT /* 分析历史SQL性能 */ DIGEST_TEXT AS normalized_sql, SUM(SUM_TIMER_WAIT)/1000000000 AS total_exec_sec, SUM(SUM_CPU_TIME)/1000000000 AS total_cpu_sec, COUNT_STAR AS exec_count FROM performance_schema.events_statements_summary_by_digest WHERE FIRST_SEEN BETWEEN '2023-11-01 14:00:00' AND '2023-11-01 15:00:00' GROUP BY DIGEST ORDER BY total_cpu_sec DESC LIMIT 10; ``` #### 3. **通用方法** **AWR/Statspack报告(Oracle)**: ```bash # 生成AWR报告 $ sqlplus / as sysdba SQL> @?/rdbms/admin/awrrpt.sql ``` 在报告中选择目标时间段,查看"SQL ordered by CPU Time"部分[^1]。 **实时监控工具**: - 使用`top`命令配合`jstack`(Java应用): ```bash # 定位CPU线程 $ top -H -p <PID> $ jstack <PID> | grep -A 20 <nid> ``` - MongoDB使用`mongotop`和`mongostat`监控实时操作[^2] #### 4. 分析要点 1. **验证时间范围**:确保监控时段与业务峰匹配 2. **关联SQL文本**:检查CPU SQL是否存在: - 全表扫描(缺少索引) - 复杂计算(如数学函数嵌套) - 低效连接(笛卡尔积) 3. **检查执行计划**:使用`EXPLAIN PLAN`分析访问路径 4. **对比基线**:与历史正常时段数据对比,确认异常波动 > **优化建议**:对频繁执行的CPU SQL,优先考虑添加缺失索引、重构业务逻辑避免客户端处理大数据、调整排序算法减少临时表使用[^1]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值