问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

oracle is null 不走索引怎么优化

发布网友 发布时间:2022-04-07 15:15

我来回答

2个回答

懂视网 时间:2022-04-07 19:36

     默认情况下,Oracle数据库,null在Index上是不被存储的,当在索引列以“is null”的方式访问时,无法使用索引;本案例,主要向大家演示如何在存在null的索引列上,使用“is null”访问索引。


案例分析:


1、建立表和普通索引

13:52:23 SCOTT@ prod >create table t2 (x int,y int);
Table created.
14:00:11 SCOTT@ prod >insert into t2 values (1,1);
1 row created.
Elapsed: 00:00:00.04
14:00:21 SCOTT@ prod >insert into t2 values (1,null);
1 row created.
Elapsed: 00:00:00.00
14:00:31 SCOTT@ prod >insert into t2 values (null,1);
1 row created.
Elapsed: 00:00:00.00
14:00:37 SCOTT@ prod >insert into t2 values (null,null);
1 row created.
Elapsed: 00:00:00.00
14:00:44 SCOTT@ prod >commit;
Commit complete.
Elapsed: 00:00:00.04
14:06:41 SCOTT@ prod >select * from t2;
         X          Y
---------- ----------
         1          1
         1
                    1
                    
14:36:12 SCOTT@ prod >create index t2_ind on t2(x);
Index created.

14:49:38 SCOTT@ prod >select index_name,table_name,num_rows from user_indexes where index_name=‘T2_IND‘;
INDEX_NAME                     TABLE_NAME                       NUM_ROWS
------------------------------ ------------------------------ ----------
T2_IND                         T2                                      3

  在索引中只有3行,在最后一行字段全为null值,没有被存储!

14:36:27 SCOTT@ prod >exec dbms_stats.gather_index_stats(user,‘T2_IND‘);
PL/SQL procedure successfully completed.

14:37:29 SCOTT@ prod >select * from t2 where x=1;
         X          Y
---------- ----------
         1          1
         1

Execution Plan
----------------------------------------------------------
Plan hash value: 1173409066
--------------------------------------------------------------------------------------
| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |     2 |     8 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T2     |     2 |     8 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | T2_IND |     2 |       |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("X"=1)
Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          4  consistent gets
          0  physical reads
          0  redo size
        519  bytes sent via SQL*Net to client
        415  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          2  rows processed
          
14:37:45 SCOTT@ prod >select * from t2 where x is not null;
         X          Y
---------- ----------
         1          1
         1

Execution Plan
----------------------------------------------------------
Plan hash value: 463061910
--------------------------------------------------------------------------------------
| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |     2 |     8 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T2     |     2 |     8 |     2   (0)| 00:00:01 |
|*  2 |   INDEX FULL SCAN           | T2_IND |     2 |       |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter("X" IS NOT NULL)
Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          4  consistent gets
          0  physical reads
          0  redo size
        519  bytes sent via SQL*Net to client
        415  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          2  rows processed
          
14:38:00 SCOTT@ prod >select * from t2 where x is null;
         X          Y
---------- ----------
                    1

Execution Plan
----------------------------------------------------------
Plan hash value: 1513984157
--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     2 |     8 |     3   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| T2   |     2 |     8 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("X" IS NULL)
Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          8  consistent gets
          0  physical reads
          0  redo size
        508  bytes sent via SQL*Net to client
        415  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          2  rows processed
当x通过“is null”访问时,Oracle选择了“full table”方式。

2、通过建立常量符合索引

14:38:55 SCOTT@ prod >create index t2_ind on t2(x,0);
Index created.

14:49:38 SCOTT@ prod >select index_name,table_name,num_rows from user_indexes where index_name=‘T2_IND‘;
INDEX_NAME                     TABLE_NAME                       NUM_ROWS
------------------------------ ------------------------------ ----------
T2_IND                         T2                                      4

   索引块上存储了表中所用的行。

14:39:50 SCOTT@ prod >select * from t2 where x is null;
         X          Y
---------- ----------
                    1
Elapsed: 00:00:00.00
Execution Plan
----------------------------------------------------------
Plan hash value: 1173409066
--------------------------------------------------------------------------------------
| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |     2 |     8 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T2     |     2 |     8 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | T2_IND |     2 |       |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("X" IS NULL)
Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          4  consistent gets
          0  physical reads
          0  redo size
        508  bytes sent via SQL*Net to client
        415  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          2  rows processed
          
对于x通过“is null”访问时,也能通过索引访问了!

3、建立复合索引(其他列为null)

13:59:40 SCOTT@ prod >create index x_ind on t2(x,y);
Index created.

14:08:29 SCOTT@ prod >EXEC dbms_stats.gather_table_stats(ownname=>USER,tabname=>‘T2‘);
PL/SQL procedure successfully completed.

14:09:22 SCOTT@ prod >EXEC dbms_stats.gather_index_stats(ownname=>USER,indname=>‘X_IND‘);
PL/SQL procedure successfully completed.

14:09:58 SCOTT@ prod >select index_name,num_rows from user_indexes where index_name=‘X_IND‘;
INDEX_NAME                       NUM_ROWS
------------------------------ ----------
X_IND                                   3

14:10:50 SCOTT@ prod >select count(*) from t2;
  COUNT(*)
----------
         4
         
14:11:28 SCOTT@ prod >set autotrace on
14:12:33 SCOTT@ prod >select * from t2 where x=1;
         X          Y
---------- ----------
         1          1
         1

Execution Plan
----------------------------------------------------------
Plan hash value: 3708139238
--------------------------------------------------------------------------
| Id  | Operation        | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT |       |     2 |     8 |     1   (0)| 00:00:01 |
|*  1 |  INDEX RANGE SCAN| X_IND |     2 |     8 |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access("X"=1)
Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          2  consistent gets
          0  physical reads
          0  redo size
        512  bytes sent via SQL*Net to client
        415  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          2  rows processed
          
14:12:47 SCOTT@ prod >select * from t2 where x is not null;
         X          Y
---------- ----------
         1          1
         1
Elapsed: 00:00:00.00
Execution Plan
----------------------------------------------------------
Plan hash value: 3776680409
--------------------------------------------------------------------------
| Id  | Operation        | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT |       |     2 |     8 |     1   (0)| 00:00:01 |
|*  1 |  INDEX FULL SCAN | X_IND |     2 |     8 |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("X" IS NOT NULL)
Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          2  consistent gets
          0  physical reads
          0  redo size
        512  bytes sent via SQL*Net to client
        415  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          2  rows processed
          
14:13:08 SCOTT@ prod >select * from t2 where x is null;
         X          Y
---------- ----------
                    1
Execution Plan
----------------------------------------------------------
Plan hash value: 1513984157
--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     2 |     8 |     3   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| T2   |     2 |     8 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("X" IS NULL)
Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          8  consistent gets
          0  physical reads
          0  redo size
        508  bytes sent via SQL*Net to client
        415  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          2  rows processed
          
 如果,复合索引列其他列也为null,在查询使用’is null‘条件时,仍然为“full table scan”。
          
14:13:52 SCOTT@ prod >select * from t2 where x=1 and y is null;
         X          Y
---------- ----------
         1

Execution Plan
----------------------------------------------------------
Plan hash value: 3708139238
--------------------------------------------------------------------------
| Id  | Operation        | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT |       |     1 |     4 |     1   (0)| 00:00:01 |
|*  1 |  INDEX RANGE SCAN| X_IND |     1 |     4 |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access("X"=1 AND "Y" IS NULL)
Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          2  consistent gets
          0  physical reads
          0  redo size
        471  bytes sent via SQL*Net to client
        415  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed
          
14:16:16 SCOTT@ prod >select * from t2 where x is null and y=1;
         X          Y
---------- ----------
                    1

Execution Plan
----------------------------------------------------------
Plan hash value: 3708139238
--------------------------------------------------------------------------
| Id  | Operation        | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT |       |     1 |     4 |     1   (0)| 00:00:01 |
|*  1 |  INDEX RANGE SCAN| X_IND |     1 |     4 |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access("X" IS NULL AND "Y"=1)
       filter("Y"=1)
Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          1  consistent gets
          0  physical reads
          0  redo size
        471  bytes sent via SQL*Net to client
        415  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

4、建立复合索引(其他列为 not null)


15:13:38 SCOTT@ prod >desc t2;
 Name                                                              Null?    Type
 ----------------------------------------------------------------- -------- --------------------------------------------
 X                                                                          NUMBER(38)
 Y                                                                          NUMBER(38)
 
15:13:43 SCOTT@ prod >alter table t2 modify (y NUMBER(38) not null);
Table altered.

15:14:01 SCOTT@ prod >desc t2;
 Name                                                              Null?    Type
 ----------------------------------------------------------------- -------- --------------------------------------------
 X                                                                          NUMBER(38)
 Y                                                                 NOT NULL NUMBER(38)
 
15:12:54 SCOTT@ prod >insert into t2 values (1,1);
1 row created.
Elapsed: 00:00:00.02
15:13:02 SCOTT@ prod >insert into t2 values (null,1);
1 row created.
Elapsed: 00:00:00.00
15:13:12 SCOTT@ prod >insert into t2 values (null,2);
1 row created.
Elapsed: 00:00:00.00
15:13:36 SCOTT@ prod >commit;
Commit complete.

15:15:00 SCOTT@ prod >create index t2_ind on t2 (x,y);
Index created.

15:15:29 SCOTT@ prod >exec dbms_stats.gather_table_stats(user,‘T2‘,cascade=>true);
PL/SQL procedure successfully completed.

15:16:09 SCOTT@ prod >select index_name,table_name,num_rows from user_indexes where index_name=‘T2_IND‘;
INDEX_NAME                     TABLE_NAME                       NUM_ROWS
------------------------------ ------------------------------ ----------
T2_IND                         T2                                      3

15:17:20 SCOTT@ prod >set autotrace trace
15:17:26 SCOTT@ prod >SELECT * from t2 where x is null
Elapsed: 00:00:00.00
Execution Plan
----------------------------------------------------------
Plan hash value: 2876512201
---------------------------------------------------------------------------
| Id  | Operation        | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT |        |     2 |    10 |     1   (0)| 00:00:01 |
|*  1 |  INDEX RANGE SCAN| T2_IND |     2 |    10 |     1   (0)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access("X" IS NULL)
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          2  consistent gets
          0  physical reads
          0  redo size
        510  bytes sent via SQL*Net to client
        415  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          2  rows processed
在复合索引中,如果其他列为not null,则在“is null”条件下,仍然可以使用索引访问。

结论:

对于普通的索引,null值不能进行索引的正确理解应该是,对于某一行,索引的所有列的值都是null值时,该行才不能被索引。



本文出自 “天涯客的blog” 博客,请务必保留此出处http://tiany.blog.51cto.com/513694/1582469

通过案例学调优之--Oracle中null使用索引

标签:oracle

热心网友 时间:2022-04-07 16:44

Oracle性能优化(一) 关注指标及复合索引原理设计指标:对sql语句进行分析,需要关注的指标字至少包括以下几个:1.消耗时间:包括Elapsed Time 、CPU Time等时间指标2.内存消耗:包括Buffer Gets、Consistant Gets等指标3.IO消耗:包括
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
巨蟹男对你不闻不问说明什么 消消怎么造句 懒腰怎么造句 世界十大名牌男装标志 策划工作室是做什么的 模型玩具是什么专业 玩魔兽世界,一周在线15小时,求高人帮忙计算一个月各种消费多少钱。 魔兽世界点卡多少钱一个月-点卡收费模式选择建议 玩魔兽世界,一天玩个15个小时,一个月得花多钱 晚上天上扫来扫去的是装饰还是警示灯? 秋天的雨作者的主要作品 用鸽子剁辣椒酱的做法 读书笔记摘抄,要求有好词10好句3,书名 心情短语 作文:我讨厌语文课或喜欢语文课 剁辣椒传统正宗制作方法 湖南辣椒酱自制 超好吃的辣椒酱制作 腰部的肌肉怎么练出来? 怎么都注册不了,怎么办 跟女朋友99天了 想发一条说说发什么好呢?希望哪些大神把我说下,谢谢! 能说说女生为什么喜欢吃果冻吗? 剁辣椒传统制作方法:湖南辣椒酱自制,超好吃的辣椒酱就是太辣 做个小调查:谈谈你吃果冻的感受。 秋天的雨周记三百字左右 手机号注册不了怎么办 语文学霸请帮忙! 我的电信卡怎么注册不了? 自然笔记枫叶的描写 我的电信卡怎么注册不了? 勾住一词,让我好像看到什么? 什么东西能解酒?? 截面是等腰三角形,高2.1米,底6.8米,长11.6米,这个三角体有多少立方? 找出图片中隐藏的动物 梯形、三角形的立方怎么算 美,令我感动的作文 图中你能找到什么动物?有16个 像这样的立方公式怎么计算求解答!谢谢! 之美,令我感动初一作文 请看图中隐藏看什么动物? 三角形一立方怎么算 生活之美 令我感动作文 请看图说出隐藏的是什么动物? 自然之美,令我感动作文600字记叙文,要把自己放进文中。急!急!_百度知 ... 请猜一猜下图中隐藏哪种动物? 等边三角形的立方米怎么算 心灵之美,令我感动作文 等腰三角形体积怎么求? 知道两条边是30,底是35求体积? 宝宝的找出图中隐藏的小羊羔小游戏需要哪些道具? 《这就是美》,作文700字,怎么写 这一幕让我感动700字以上的作文 等腰三角形的面积公式是什么,怎么算