• 【转】Oracle索引列NULL值引发执行计划该表的测试示例 water


    有时开发进行表结构设计,对表字段是否为空过于随意,出现诸如id1=id2,如果允许字段为空,因为Oracle中空值并不等于空值,有可能得到意料之外的结果。除此之外,最关键的是,NULL会影响oracle的执行计划。

    以下为NULL影响执行计划的测试示例。

    /*1.构建test表,其中create table方式建立的test表结构object_id非空*,走索引/

    SELECT Count(*) FROM all_objects WHERE object_id IS NOT NULL; --41790笔
    DROP TABLE test;
    CREATE TABLE test AS SELECT * FROM all_objects WHERE object_id IS NOT NULL; ----41791笔
    CREATE INDEX idx_test ON test(object_id);
    ANALYZE TABLE test compute STATISTICS FOR TABLE FOR ALL indexes FOR ALL indexed COLUMNS;
    EXPLAIN PLAN FOR SELECT Count(*) FROM test;
    SELECT * FROM TABLE(dbms_xplan.display);

    Plan hash value: 3508397080                                              
                                                                             
    --------------------------------------------------------------------------
    | Id  | Operation             | Name     | Rows  | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------
    |   0 | SELECT STATEMENT      |          |     1 |    23   (5)| 00:00:01 |
    |   1 |  SORT AGGREGATE       |          |     1 |            |          |
    |   2 |   INDEX FAST FULL SCAN| IDX_TEST | 41791 |    23   (5)| 00:00:01 |
    --------------------------------------------------------------------------

    /*2.改变test表结构,使得object_id字段为NULL,并更新一笔资料为NULL*,走全表/

    ALTER TABLE test MODIFY object_id NUMBER NULL;
    UPDATE test SET object_id=NULL WHERE ROWNUM=1;
    COMMIT;
    EXPLAIN PLAN FOR SELECT Count(*) FROM test;
    SELECT * FROM TABLE(dbms_xplan.display);
    Plan hash value: 1950795681                                       
                                                                      
    -------------------------------------------------------------------
    | Id  | Operation          | Name | Rows  | Cost (%CPU)| Time     |
    -------------------------------------------------------------------
    |   0 | SELECT STATEMENT   |      |     1 |   135   (2)| 00:00:02 |
    |   1 |  SORT AGGREGATE    |      |     1 |            |          |
    |   2 |   TABLE ACCESS FULL| TEST | 41791 |   135   (2)| 00:00:02 |
    -------------------------------------------------------------------

    /*3.对SQL指令增加条件过滤NULL之资料*,走索引/

    EXPLAIN PLAN FOR SELECT Count(*) FROM test WHERE object_id IS NOT NULL;
    SELECT * FROM TABLE(dbms_xplan.display);
    Plan hash value: 3508397080                                                      
                                                                                     
    ----------------------------------------------------------------------------------
    | Id  | Operation             | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
    ----------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT      |          |     1 |     4 |    23   (5)| 00:00:01 |
    |   1 |  SORT AGGREGATE       |          |     1 |     4 |            |          |
    |*  2 |   INDEX FAST FULL SCAN| IDX_TEST | 41791 |   163K|    23   (5)| 00:00:01 |
    ----------------------------------------------------------------------------------
                                                                                     
    Predicate Information (identified by operation id):                              
    ---------------------------------------------------                              
                                                                                     
       2 - filter("OBJECT_ID" IS NOT NULL)                                           

    /*4.将上面改的那笔object_id is NULL的资料delete掉,再查看plan,依然走全表*/

    DELETE FROM test WHERE object_id IS NULL;
    COMMIT;
    ANALYZE TABLE test compute STATISTICS FOR TABLE FOR ALL indexes FOR ALL indexed COLUMNS;
    EXPLAIN PLAN FOR SELECT Count(*) FROM test;
    SELECT * FROM TABLE(dbms_xplan.display); 

    Plan hash value: 1950795681                                       
                                                                      
    -------------------------------------------------------------------
    | Id  | Operation          | Name | Rows  | Cost (%CPU)| Time     |
    -------------------------------------------------------------------
    |   0 | SELECT STATEMENT   |      |     1 |   135   (2)| 00:00:02 |
    |   1 |  SORT AGGREGATE    |      |     1 |            |          |
    |   2 |   TABLE ACCESS FULL| TEST | 41790 |   135   (2)| 00:00:02 |
    -------------------------------------------------------------------

    综上,看起来,假如索引列的表结构非空,则会走索引;若索引列表结构可空,则无论是否存在null资料,都会走全表;可以用where 索引列 is not null过滤空资料,则还是会走索引。

    转自:http://www.linuxidc.com/Linux/2012-09/69938.htm

  • 相关阅读:
    jquery.validate.unobtrusive的使用
    企业库判断数据库连接类型
    win10下安装LoadRunner12汉化包
    win10安装LoadRunner时,安装.net framwork组件报0x800F081F错误 解决办法
    wrk性能测试(详解)
    wrk压测报错 LF character expected at 1:111
    Linux scp命令详解(服务器之间复制文件或目录)
    Linux cat命令详解(连接文件并打印到标准输出设备上)
    性能测试流程
    ‘mysql’不是内部或外部命令,也不是可运行的程序--解决方法
  • 原文地址:https://www.cnblogs.com/autumnlj/p/5754284.html
Copyright © 2020-2023  润新知