• 隐式类型转换导致索引列不走索引


    请记住:Oracle一般都会根据统计信息生成相对高效的执行计划,如果没有,那肯定是有理由的。不要慌乱,需要仔细分析原因。

    测试数据:
    SQL> select count(*) from t2;
     COUNT(*)
    ----------
    106688
    SQL> create index i_t2_objectid on t2(object_id);
    索引已创建。
    SQL> analyze table t2 compute statistics for table for all indexes for all indexed columns;
    表已分析。
    SQL> desc t2;
    名称 是否为空? 类型
    ----------------------------------------- -------- ----------------------------
    OWNER VARCHAR2(30)
    OBJECT_NAME VARCHAR2(128)
    SUBOBJECT_NAME VARCHAR2(30)
    OBJECT_ID VARCHAR2(100)
    DATA_OBJECT_ID NUMBER
    OBJECT_TYPE VARCHAR2(19)
    CREATED DATE
    LAST_DDL_TIME DATE
    TIMESTAMP VARCHAR2(19)
    STATUS VARCHAR2(7)
    TEMPORARY VARCHAR2(1)
    GENERATED VARCHAR2(1)
    SECONDARY VARCHAR2(1)
    NAMESPACE NUMBER
    EDITION_NAME VARCHAR2(30)
    SQL> set autot trace
    varchar没有number的优先级高,需要先将varchar隐式类型转换成number,再和20进行比较。
    隐式类型转换导致object_id字段不走索引。
    SQL> select * from t2 where object_id=20;
    已选择8行。

    执行计划
    ----------------------------------------------------------
    Plan hash value: 1513984157
    --------------------------------------------------------------------------
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    --------------------------------------------------------------------------
    | 0 | SELECT STATEMENT | | 8 | 744 | 411 (1)| 00:00:05 |
    |* 1 | TABLE ACCESS FULL| T2 | 8 | 744 | 411 (1)| 00:00:05 |
    --------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       1 - filter(TO_NUMBER("OBJECT_ID")=20)

    统计信息
    ----------------------------------------------------------
    1 recursive calls
    0 db block gets
    1465 consistent gets
    0 physical reads
    0 redo size
    1536 bytes sent via SQL*Net to client
    416 bytes received via SQL*Net from client
    2 SQL*Net roundtrips to/from client
    0 sorts (memory)
    0 sorts (disk)
    8 rows processed
    SQL> /
    已选择8行。

    执行计划
    ----------------------------------------------------------
    Plan hash value: 1513984157
    --------------------------------------------------------------------------
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    --------------------------------------------------------------------------
    | 0 | SELECT STATEMENT | | 8 | 744 | 411 (1)| 00:00:05 |
    |* 1 | TABLE ACCESS FULL| T2 | 8 | 744 | 411 (1)| 00:00:05 |
    --------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       1 - filter(TO_NUMBER("OBJECT_ID")=20)

    统计信息
    ----------------------------------------------------------
    0 recursive calls
    0 db block gets
    1465 consistent gets
    0 physical reads
    0 redo size
    1536 bytes sent via SQL*Net to client
    416 bytes received via SQL*Net from client
    2 SQL*Net roundtrips to/from client
    0 sorts (memory)
    0 sorts (disk)
    8 rows processed
    将20显示转换成字符类型,object_id字段无需类型转换,用到索引。逻辑读为11,比全表扫描时1465下降的比例很大。
    SQL> select * from t2 where object_id='20';
    已选择8行。

    执行计划
    ----------------------------------------------------------
    Plan hash value: 1119120461
    ---------------------------------------------------------------------------------------------
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    ---------------------------------------------------------------------------------------------
    | 0 | SELECT STATEMENT | | 8 | 744 | 9 (0)| 00:00:01 |
    | 1 | TABLE ACCESS BY INDEX ROWID| T2 | 8 | 744 | 9 (0)| 00:00:01 |
    |* 2 | INDEX RANGE SCAN | I_T2_OBJECTID | 8 | | 1 (0)| 00:00:01 |
    ---------------------------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       2 - access("OBJECT_ID"='20')

    统计信息
    ----------------------------------------------------------
    1 recursive calls
    0 db block gets
    11 consistent gets
    0 physical reads
    0 redo size
    1980 bytes sent via SQL*Net to client
    416 bytes received via SQL*Net from client
    2 SQL*Net roundtrips to/from client
    0 sorts (memory)
    0 sorts (disk)
    8 rows processed
    SQL> /
    已选择8行。

    执行计划
    ----------------------------------------------------------
    Plan hash value: 1119120461
    ---------------------------------------------------------------------------------------------
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    ---------------------------------------------------------------------------------------------
    | 0 | SELECT STATEMENT | | 8 | 744 | 9 (0)| 00:00:01 |
    | 1 | TABLE ACCESS BY INDEX ROWID| T2 | 8 | 744 | 9 (0)| 00:00:01 |
    |* 2 | INDEX RANGE SCAN | I_T2_OBJECTID | 8 | | 1 (0)| 00:00:01 |
    ---------------------------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       2 - access("OBJECT_ID"='20')

    统计信息
    ----------------------------------------------------------
    0 recursive calls
    0 db block gets
    11 consistent gets
    0 physical reads
    0 redo size
    1980 bytes sent via SQL*Net to client
    416 bytes received via SQL*Net from client
    2 SQL*Net roundtrips to/from client
    0 sorts (memory)
    0 sorts (disk)
    8 rows processed
    SQL>

    另外,索引列使用函数(除非建了索引函数)、表达式、绑定变量窥测(由于执行计划共享会使用第一个传入值生成的执行计划,如果第一个生成的执行计划不使用索引,则之后就算传入值使用索引会更高效,也不会使用索引)、统计信息老旧等原因也会导致索引列不会用到索引,也需要注意可能根据索引列查询出的数据量较大,Oracle判断不走索引可能会高效也会忽略索引。在优化过程中,如果碰到索引列没有走索引,不要慌乱,Oracle对索引列不走索引都是有依据的,需要按实际情况进行分析。
  • 相关阅读:
    if elseif else
    java编程思想第四版中net.mindview.util包
    eclipse git插件配置
    php面试常用算法
    数据库字段类型中char和Varchar区别
    MySQL的数据库引擎的类型及区别
    windows系统中eclipse C c++开发环境的搭建
    launch failed.Binary not found in Linux/Ubuntu解决方案
    技术团队的情绪与效率
    如何有效使用Project(2)——进度计划的执行与监控
  • 原文地址:https://www.cnblogs.com/zhaoshuangshuang/p/3237881.html
Copyright © 2020-2023  润新知