一个SQL性能问题的优化探索(一)(r11笔记第33天)

作者: admin 分类: 公众号存档            2 次浏览 发布时间: 2017-01-03 23:42

公众号:杨建荣的学习笔记 · 作者:杨建荣 · 发布:2017-01-03 23:42:04 · 原文链接

今天同事问我一个问题,看起来比较常规,但是仔细分析了一圈,发现实在是有些晕,我隐隐感觉这是一个bug,但是有感觉问题还有很多需要确认和理解的细节。

    同事说有个10gR2的数据库SQL语句有性能问题,DB time有报警,但是还没有明确的思路,让我帮忙看看有什么好的建议。我也没有问是哪个SQL语句,根据IP登录到服务器端查看了下数据库的负载,发现负载已经有了较大的波动。这是事后补充的一张较为全面的DB time监控图。

   然后根据负载的情况,定位了大体的时间范围,就大体是11点左右。

得到了一个SQL的DB time占比图,可以很清楚看到是一个SQL导致了性能消耗极大。

 SNAP_ID SQL_ID        EXECUTIONS_DELTA ELAPSED_TI PER_TOTAL
---------- ------------- ---------------- ---------- ----------
    108652 5dw94xr3c8hy8                4 4338s      92%
    108652 0p1ntk9bv0hrr             6582 20s        0%
    108652 2bfm7hrkwu0s7             1240 0s         0%
    108652 3qd7k5q9gsnmx              434 4s         0%
    108652 4c075dx0fqsjk             7530 1s         0%    马上定位到这个SQL语句,和同事确认,就是这个语句,看语句的执行情况,可以看到执行的效率很差,这个SQL语句大体是下面的样子。

SQL_FULLTEXT
----------------------------------------------------------------------------------------------------
SELECT ID,CN,CARD_NO,TO_CHAR(CHARGE_DATE,'yyyy-MM-dd HH24:mi:ss') AS CHARGE_DATE ,IP,POINT,PRESENT_P
OINT,SUCCESS,CARD_TYPE,PRODUCTNUM,SALEMETHOD,ITEM_ID,SERVICEID,ORDER_NO,TO_CHAR(EXPIREDATE,'yyyy-MM-
dd HH24:mi:ss') AS EXPIREDATE,REMARK FROM RECHARGE_LOG WHERE CARD_NO = TO_NUMBER(:1)

   看到这个地方,很明显是SQL的性能问题,而性能瓶颈似乎在于过滤条件,是不是隐式转换导致的全表扫描呢?

   查看执行计划,我发现说对了一半,确实是全表扫描,而另一半就很难说得清楚了。因为这个表的字段CARD_NO数据类型是number(20,0),对于隐式转换,其实对于varchar2->number 的方式是兼容的,而反过来number->varchar2就很容易出现问题,具体可以参考:

MySQL和Oracle中的隐式转换(r6笔记第45天)

语句的执行计划如下:

admin

杨建荣,《Oracle DBA工作笔记》《MySQL DBA工作笔记》作者,dbaplus社群发起人之一,腾讯云TVP,现任竞技世界系统部经理,拥有十多年数据库开发和运维经验,目前专注于开源技术、运维自动化和性能调优

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注