转载

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

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

通过top命令抓取了如下的信息。

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

pid是3585的进程对应的sql 之前已经确定是性能问题导致的了,所以先放过,可以看看pid是8879的这个进程,出现的不是很“稳定”。

可能通过ash,awr不一定能够及时的抓住这些信息,但是通过及时的分析,可能有时候会得到一想不到的收获。

可以通过v$session,v$process,v$sql来结合查找process对应的sql.

可以看到这个进程是属于一个远程的session(LOCAL=NO),是通过一个batch的服务器上发起的请求。

执行的sql很简单。就是一个简单的查询。初步怀疑就是因为查询走了全表扫描而且那个字段可能没有索引。

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

为了确认,查看表的结构来看看。可以结合user_tab_cols,user_ind_columns来查看表的属性和索引的信息。这些都是用准备好的脚本来生成的,过滤了一些不必要的信息。

可以看到,索引是存在的,在ext_account_number上,而且是唯一性索引。如果那样的话走全表扫描就有些不合常理了。

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

如果观察的再仔细些,可以看到ext_account_number那个字段是varchar2(12)的。

为了验证表肯定走了全表扫描,我抓了一个awrsqrpt的报告。内容如下,可以看到的确走了全表扫描。而且buffer gets还挺大,cpu消耗比较高。

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

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

我从表里随机抓取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.

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

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

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

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#;
正文到此结束
Loading...