暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

FF009-一个索引拯救了一个exadata

这是一个非常典型的索引优化案例,我在2021年06月15日<优化的故事及大型生产系统性能优化实战>培训  中的故事篇里面提到过, 一个SQL占了一个exadata高级硬件环境的绝大部分资源, 平均执行时间51秒. 今天我再详细分析一下这个案例.

下面截取的是AWR按执行时间排名的top SQL:


下面截取的是分别按CPU,磁盘读,逻辑读排名的Top SQL,:

从上面的截图可见, 该系统的一个Top SQL消耗的一多半的系统资源.


SQL比较简单, 就是一个单表查询, 表不算太大, 370多万记录, 占用空间13G,一个贷款业务, 历史数据不能清理. 

用户也尝试建了一个3字段索引, 但是用不上, 执行计划还是全表扫描. sql_text及索引如下:

    SELECT *
    FROM CUSTOM_APPLY_xxx
    WHERE (
    (TO_DATE(:1 , 'YYYYMMDDHH24MISS') >= TO_DATE(CREATE_TIME, 'YYYYMMDDHH24MISS')
    AND PUSH_CREDIT_FLAG = 'I')
    OR
    (PUSH_CREDIT_FLAG = 'F' AND PUSH_CREDIT_COUNT > 3)
    )
    AND (CREDIT_REPORT_TYPE = '1' or CREDIT_REPORT_TYPE is null);


    --创建的索引如下:
    CREATE INDEX "IDX_CUSTOM_APPLY_xxx" ON "CUSTOM_APPLY_xxx" 
    ("CREATE_TIME""PUSH_CREDIT_COUNT""PUSH_CREDIT_FLAG");


    看到这里, 不知道各位读者有什么优化思路?

    有优化经验的人可能一眼就看到了一个问题: create_time字段上使用了to_date函数, 导致索引失效.  

    TO_DATE(:1 , 'YYYYMMDDHH24MISS') >= TO_DATE(CREATE_TIME, 'YYYYMMDDHH24MISS') 这个写法确实不够规范, 也是我在给很多的开发人员培训时多次强调的. 

    把create_time字段上的to_date函数去掉,或者改成to_date函数索引就行了吗? 

    文章转载自老虎刘谈oracle性能优化,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

    评论