通过top命令抓取cpu高消耗的sql

本文通过使用top命令分析Linux环境下性能问题SQL,详细介绍了如何通过查询PID、结合v$session、v$process、v$sql等视图定位具体进程及SQL语句,进而深入分析并解决SQL执行效率低下问题,包括查询全表扫描、类型转换、索引使用情况等关键信息。

top命令在linux环境维护中很实用,虽然功能缺失不够sar那么全面。今天和大家分享一个通过top命令来抓取性能sql的案例。
通过top命令抓取了如下的信息。

 pid是3585的进程对应的sql 之前已经确定是性能问题导致的了,所以先放过,可以看看pid是8879的这个进程,出现的不是很“稳定”。
可能通过ash,awr不一定能够及时的抓住这些信息,但是通过及时的分析,可能有时候会得到一想不到的收获。
可以通过v$session,v$process,v$sql来结合查找process对应的sql.
可以看到这个进程是属于一个远程的session(LOCAL=NO),是通过一个batch的服务器上发起的请求。
执行的sql很简单。就是一个简单的查询。初步怀疑就是因为查询走了全表扫描而且那个字段可能没有索引。

 为了确认,查看表的结构来看看。可以结合user_tab_cols,user_ind_columns来查看表的属性和索引的信息。这些都是用准备好的脚本来生成的,过滤了一些不必要的信息。
可以看到,索引是存在的,在ext_account_number上,而且是唯一性索引。如果那样的话走全表扫描就有些不合常理了。

 如果观察的再仔细些,可以看到ext_account_number那个字段是varchar2(12)的。
为了验证表肯定走了全表扫描,我抓了一个awrsqrpt的报告。内容如下,可以看到的确走了全表扫描。而且buffer gets还挺大,cpu消耗比较高。

 到此为止,如果还不没明白的话,我做个简单的测试。

我从表里随机抓取10条记录。
SQL> SELECT balance ,EXT_ACCOUNT_NUMBER from ACCOUNT WHERE rownum<=10;   
                                                                         
BALANCE EXT_ACCOUNT_NUMBER
---------- ------------                                                  
         0 10257832                                                      
    772.81 10260829                                                      
    584.22 10259790                                                      
    329.03 10258781                                                      
      -.39 10263317                                                      
      -.14 10260830                                                      
    496.79 10258782                                                      
         0 10258783                                                      
      -.83 10258785                                                      
      -.91 10259791                                                      
                                                                         
10 rows selected.                                                        
然后来trace一把。看看执行的情况。
可以看到,确实走了全表扫描,没有走索引。可以看到filter部分,对于ext_account_number它是在解析的时候做了类型转换的,从varchar2转为number。
一致性读有12704.

 这样问题的根源就很清晰了。再换一个,试试走索引的情况。可以看到,效率有了极大的提升。剩下的问题就是协调来解决了。

 

select ses.sid,ses.serial#,ses.username,ses.machine,ses.osuser,pro.terminal,ses.type,ses.logon_time,sql.sql_text
from v$session ses, v$process pro, v$sql sql
 where ses.paddr = pro.addr
   and ses.SQL_HASH_VALUE = sql.HASH_VALUE
   and ses.SQL_ADDRESS = sql.address
   and  ses.sql_address = sql.address
   and pro.pid = #pid#;

 

<think>好的,我现在需要帮助用户解决服务器CPU负载过的问题。首先,我得仔细看看用户提供的引用资料,里面提到了一些可能的原因和解决方案。用户已经给出五个引用,我需要结合这些信息来整理出有效的解决步骤。 首先,根据引用[2],处于RUNNABLE状态的线程如果是纯Java运算,会消耗CPU,而网络IO等待时不消耗。这可能意味着需要检查应用程序中是否有CPU消耗的代码。引用[4]提到kswapd0进程频繁分页导致CPU负载,这可能和内存不足有关,导致频繁使用交换分区。引用[5]中的vmstat输出显示有较的系统中断(in)和上下文切换(cs),可能暗示进程调度频繁或IO问题。 接下来,我需要整理一个系统化的排查流程。用户可能需要逐步检查CPU使用率、负载情况,然后分析进程和线程,查看是否有异常的进程占用过资源。比如使用top或htop命令查看实时情况。然后,利用性能分析工具如perf或jstack来定位具体代码问题,如果是Java应用的话。 然后,优化方向可能包括代码层面的优化,比如减少不必要的计算,优化算法,或者引入缓存机制。另外,调整系统参数,比如虚拟内存设置,减少分页操作,或者调整线程池配置,避免过多线程竞争CPU资源。同时,负载均衡策略也很重要,如引用[1]提到的Nginx配置,可以通过一致性哈希等方法分散请求,避免单节点过载。 需要注意的是,引用[3]强调不能单纯调大参数,而是要理解原理,根据环境调整。所以解决方案需要针对具体情况,比如如果是数据库查询慢导致CPU,可能需要优化SQL语句或索引。 最后,总结时需要分步骤,结构清晰,确保用户能够逐步实施。同时生成相关问题,帮助用户深入理解问题,比如如何分析线程状态、内存不足如何处理等。</think>### 如何降低服务器CPU负载过的解决方案 #### 一、排查问题根源 1. **查看CPU使用率与负载关系** 使用`top`或`htop`命令确认CPU使用率(%CPU)与负载(Load Average)是否匹配。若负载CPU使用率低,可能由以下原因导致: - 内存不足触发频繁分页(kswapd0进程活跃)[^4] - I/O等待(如磁盘或网络阻塞) - 进程竞争锁导致的线程阻塞[^2] 2. **分析进程与线程状态** - 通过`pidstat -t -p <PID> 1`查看线程状态,重点关注处于`RUNNABLE`的线程是否执行纯计算任务[^2] - 使用`vmstat 1`检查`cs`(上下文切换)和`wa`(I/O等待)指标,若`wa`持续>10%,需优化I/O[^5] ```bash procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 1 0 0 2684984 310452 2364304 0 0 5 17 19 35 4 2 94 0 0 ``` 3. **定位消耗代码** - Java应用:使用`jstack <PID>`导出线程堆栈,分析`RUNNABLE`线程的代码逻辑 - C/C++应用:通过`perf top`或`gdb`抓取热点函数 - PHP应用:结合Xdebug生成函数调用跟踪日志[^3] --- #### 二、针对性优化措施 1. **内存不足场景** - 增加物理内存或减少内存占用 - 调整`/proc/sys/vm/swappiness`降低交换分区使用优先级[^4] - 优化程序内存分配(如避免内存泄漏、使用对象池) 2. **I/O密集型场景** - 数据库优化:添加索引、拆分大查询、启用缓存 - 文件读写:使用SSD替换HDD,或采用内存文件系统(如tmpfs) - 网络IO:升级网卡、启用TCP Fast Open 3. **计算密集型场景** - 代码级优化: - 避免嵌套循环(时间复杂度优化) - 使用空间换时间(如预计算、缓存结果) - 并行化处理(如多线程/进程、GPU加速) - 算法优化: - 替换$O(n^2)$算法为$O(n\log n)$算法(如快速排序替代冒泡排序) $$T(n) = 2T(n/2) + O(n) \Rightarrow O(n\log n)$$ 4. **配置调优示例** ```nginx # Nginx负载均衡配置(减少单节点压力)[^1] upstream cluster { server srv1 weight=3; # 权重分配 server srv2; server srv3 backup; # 备用服务器 fair; # 公平调度 } ``` --- #### 三、长期监控与防护 1. **建立基线指标** - 通过`sar -u 1 10`记录正常CPU使用模式 - 使用Prometheus+Grafana设置阈值告警 2. **防御性设计** - 限流降级:通过令牌桶算法限制QPS - 自动扩容:Kubernetes HPA根据CPU负载弹性伸缩 --- 相关问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值