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

2024年 7月 20日 85.7k 0

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

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

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

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

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

从上面的截图可见, 该系统的一个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如何使用授予和撤销权限的语法和示例
    Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
    下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
    社区版oceanbase安装
    Oracle 导出CSV工具-sqluldr2
    ETL数据集成丨快速将MySQL数据迁移至Doris数据库

    发布评论