一个SQL性能问题的优化探索(一)(r11笔记第33天)
公众号:杨建荣的学习笔记 · 作者:杨建荣 · 发布: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_POINT,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就很容易出现问题,具体可以参考:
语句的执行计划如下:

