[20121028]IOT的第2索引-NULL的问题.txt

[20121028]IOT的第2索引-NULL的问题.txt
IOT表实际上时索引结构,如果第2索引的键值为NULL,会是什么情况呢?
因为第2索引包含主键,而主键是不能为NULL的,这样即使第2索引的键值为NULL,会包括在第2索引中吗?
自己做一些测试验证看看:
1.测试环境:
SQL> select * from v$version where rownum
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
SQL> create table t_iot ( a varchar2(10),b varchar2(10),vc varchar2(1200), constraint t_iot_pk PRIMARY KEY(a)) ORGANIZATION INDEX;
SQL> create index i_t_iot_b on t_iot(b);
insert into t_iot values ('1'        ,'a','a');
insert into t_iot values ('22'       ,'b','a');
insert into t_iot values ('333'      ,'c','a');
insert into t_iot values ('4444'     ,'d','a');
insert into t_iot values ('55555'    ,'e','a');
insert into t_iot values ('666666'   ,'f','a');
insert into t_iot values ('7777777'  ,'g','a');
insert into t_iot values ('88888888' ,'h','a');
commit ;
SQL> exec dbms_stats.gather_table_stats(ownname=>USER, tabname=>'T_iot');

2.看看主键为NULL,可以插入吗?
insert into t_iot values (NULL,'j','a');
                          *
ERROR at line 1:
ORA-01400: cannot insert NULL into ("SCOTT"."T_IOT"."A")
SQL> insert into t_iot values ('999999999',NULL,'b');
1 row created.
SQL> commit ;
Commit complete.

3.查询测试:
SQL> select /*+ index(t1,i_t_iot_b) */ a,b,substr(vc,1,40) from t_iot where b is null;
A          B          SUBSTR(VC,1,40)
---------- ---------- ---------------
999999999             b
SQL> @dpc 
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  6wzax9paxk4ag, child number 0
-------------------------------------
select /*+ index(t1,i_t_iot_b) */ a,b,substr(vc,1,40) from t_iot where
b is null
Plan hash value: 2901191065
-----------------------------------------------------------
| Id  | Operation        | Name     | E-Rows | Cost (%CPU)|
-----------------------------------------------------------
|   0 | SELECT STATEMENT |          |        |     1 (100)|
|*  1 |  INDEX FULL SCAN | T_IOT_PK |      1 |     1   (0)|
-----------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("B" IS NULL)
--可以发现并不使用第2索引i_t_iot_b.
SQL> select /*+ index(t1,i_t_iot_b) */ a,b,substr(vc,1,40) from t_iot where b='a';
A          B          SUBSTR(VC,1,40)
---------- ---------- ---------------
1          a          a
SQL> @dpc
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  9631w0zracpn8, child number 0
-------------------------------------
select /*+ index(t1,i_t_iot_b) */ a,b,substr(vc,1,40) from t_iot where
b='a'
Plan hash value: 1095339046
-------------------------------------------------------------
| Id  | Operation         | Name      | E-Rows | Cost (%CPU)|
-------------------------------------------------------------
|   0 | SELECT STATEMENT  |           |        |     1 (100)|
|*  1 |  INDEX UNIQUE SCAN| T_IOT_PK  |      1 |     1   (0)|
|*  2 |   INDEX RANGE SCAN| I_T_IOT_B |      1 |     1   (0)|
-------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access("B"='a')
   2 - access("B"='a')

4.转储第2索引 i_t_iot_b:
SQL> select header_file,header_block from dba_segments where segment_name='I_T_IOT_B';
HEADER_FILE HEADER_BLOCK
----------- ------------
          4          522
SQL> select object_id,data_object_id from dba_objects where object_name='I_T_IOT_B';
 OBJECT_ID DATA_OBJECT_ID
---------- --------------
    117537         117537
SQL> ALTER SESSION SET EVENTS 'immediate trace name treedump level 117537';
----- begin tree dump
leaf: 0x100020b 16777739 (0: nrow: 8 rrow: 8)
----- end tree dump
仅仅占用1个块。HEADER_BLOCK=533,根节点=523.
SQL> alter system dump datafile 4 block 523 ;
Block header dump:  0x0100020b
 Object id on Block? Y
 seg/obj: 0x1cb21  csc: 0x00.b3748a14  itc: 2  flg: E  typ: 2 - INDEX
     brn: 0  bdba: 0x1000208 ver: 0x01 opc: 0
     inc: 0  exflg: 0
 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x02   0x0007.00c.00002319  0x00c041b1.1296.50  --U-    8  fsc 0x0000.b3748a1e
Leaf block dump
===============
header address 182924685412=0x2a97293064
kdxcolev 0
KDXCOLEV Flags = - - -
kdxcolok 0
kdxcoopc 0x90: pcode=0: iot flags=I-- is converted=Y
kdxconco 2
kdxcosdc 0
kdxconro 8
kdxcofbo 52=0x34
kdxcofeo 7892=0x1ed4
kdxcoavs 7840
kdxlespl 0
kdxlende 0
kdxlenxt 0=0x0
kdxleprv 0=0x0
kdxledsz 0
kdxlebksz 8032
row#0[8018] flag: K-----, lock: 2, len=14
col 0; len 1; (1):  61
col 1; len 1; (1):  31
tl: 8 fb: --H-FL-- lb: 0x0  cc: 1
col  0: [ 4]  01 00 00 a3
row#1[8003] flag: K-----, lock: 2, len=15
col 0; len 1; (1):  62
col 1; len 2; (2):  32 32
tl: 8 fb: --H-FL-- lb: 0x0  cc: 1
col  0: [ 4]  01 00 00 a3
row#2[7987] flag: K-----, lock: 2, len=16
col 0; len 1; (1):  63
col 1; len 3; (3):  33 33 33
tl: 8 fb: --H-FL-- lb: 0x0  cc: 1
col  0: [ 4]  01 00 00 a3
row#3[7970] flag: K-----, lock: 2, len=17
col 0; len 1; (1):  64
col 1; len 4; (4):  34 34 34 34
tl: 8 fb: --H-FL-- lb: 0x0  cc: 1
col  0: [ 4]  01 00 00 a3
row#4[7952] flag: K-----, lock: 2, len=18
col 0; len 1; (1):  65
col 1; len 5; (5):  35 35 35 35 35
tl: 8 fb: --H-FL-- lb: 0x0  cc: 1
col  0: [ 4]  01 00 00 a3
row#5[7933] flag: K-----, lock: 2, len=19
col 0; len 1; (1):  66
col 1; len 6; (6):  36 36 36 36 36 36
tl: 8 fb: --H-FL-- lb: 0x0  cc: 1
col  0: [ 4]  01 00 00 a3
row#6[7913] flag: K-----, lock: 2, len=20
col 0; len 1; (1):  67
col 1; len 7; (7):  37 37 37 37 37 37 37
tl: 8 fb: --H-FL-- lb: 0x0  cc: 1
col  0: [ 4]  01 00 00 a3
row#7[7892] flag: K-----, lock: 2, len=21
col 0; len 1; (1):  68
col 1; len 8; (8):  38 38 38 38 38 38 38 38
tl: 8 fb: --H-FL-- lb: 0x0  cc: 1
col  0: [ 4]  01 00 00 a3
----- end of leaf block dump -----
End dump data blocks tsn: 4 file#: 4 minblk 523 maxblk 523
--可以发现并没有NULL.这点有点奇怪,oracle的第2索引包含主键,而主键是非空的.

5.建立函数索引看看.
SQL> create index if_t_iot_b on t_iot(b,0);
Index created.
SQL> select header_file,header_block from dba_segments where segment_name='IF_T_IOT_B';
HEADER_FILE HEADER_BLOCK
----------- ------------
          4          530
SQL> alter system dump datafile 4 block 531 ;
System altered.
Block header dump:  0x01000213
 Object id on Block? Y
 seg/obj: 0x1cb1b  csc: 0x00.b374789f  itc: 3  flg: E  typ: 1 - DATA
"/u01/app/oracle11g/diag/rdbms/test/test/trace/test_ora_10830.trc" 1276L, 65346C                                                                                                         551,1         42%
kdxconro 9
kdxcofbo 54=0x36
kdxcofeo 7853=0x1ead
kdxcoavs 7799
kdxlespl 0
kdxlende 0
kdxlenxt 0=0x0
kdxleprv 0=0x0
kdxledsz 0
kdxlebksz 8032
row#0[8016] flag: K-----, lock: 0, len=16
col 0; len 1; (1):  61
col 1; len 1; (1):  80
col 2; len 1; (1):  31
tl: 8 fb: --H-FL-- lb: 0x0  cc: 1
col  0: [ 4]  01 00 00 a3
row#1[7999] flag: K-----, lock: 0, len=17
col 0; len 1; (1):  62
col 1; len 1; (1):  80
col 2; len 2; (2):  32 32
tl: 8 fb: --H-FL-- lb: 0x0  cc: 1
col  0: [ 4]  01 00 00 a3
row#2[7981] flag: K-----, lock: 0, len=18
col 0; len 1; (1):  63
col 1; len 1; (1):  80
col 2; len 3; (3):  33 33 33
tl: 8 fb: --H-FL-- lb: 0x0  cc: 1
col  0: [ 4]  01 00 00 a3
row#3[7962] flag: K-----, lock: 0, len=19
col 0; len 1; (1):  64
col 1; len 1; (1):  80
col 2; len 4; (4):  34 34 34 34
tl: 8 fb: --H-FL-- lb: 0x0  cc: 1
col  0: [ 4]  01 00 00 a3
row#4[7942] flag: K-----, lock: 0, len=20
col 0; len 1; (1):  65
col 1; len 1; (1):  80
col 2; len 5; (5):  35 35 35 35 35
tl: 8 fb: --H-FL-- lb: 0x0  cc: 1
col  0: [ 4]  01 00 00 a3
row#5[7921] flag: K-----, lock: 0, len=21
col 0; len 1; (1):  66
col 1; len 1; (1):  80
col 2; len 6; (6):  36 36 36 36 36 36
tl: 8 fb: --H-FL-- lb: 0x0  cc: 1
col  0: [ 4]  01 00 00 a3
row#6[7899] flag: K-----, lock: 0, len=22
col 0; len 1; (1):  67
col 1; len 1; (1):  80
col 2; len 7; (7):  37 37 37 37 37 37 37
tl: 8 fb: --H-FL-- lb: 0x0  cc: 1
col  0: [ 4]  01 00 00 a3
row#7[7876] flag: K-----, lock: 0, len=23
col 0; len 1; (1):  68
col 1; len 1; (1):  80
col 2; len 8; (8):  38 38 38 38 38 38 38 38
tl: 8 fb: --H-FL-- lb: 0x0  cc: 1
col  0: [ 4]  01 00 00 a3
row#8[7853] flag: K-----, lock: 0, len=23
col 0; NULL
col 1; len 1; (1):  80
col 2; len 9; (9):  39 39 39 39 39 39 39 39 39
tl: 8 fb: --H-FL-- lb: 0x0  cc: 1
col  0: [ 4]  01 00 00 a3
----- end of leaf block dump -----
End dump data blocks tsn: 4 file#: 4 minblk 531 maxblk 531
--可以发现函数包括NULL,因为我建立的函数索引包含一个常量0.

SQL> select /*+ index(t1 IF_T_IOT_B ) */ a,b,substr(vc,1,40) from t_iot where b is  null;
A          B          SUBSTR(VC,1,40)
---------- ---------- ----------------
999999999             b
SQL> @dpc
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  9s3ryp5xzyyjs, child number 0
-------------------------------------
select /*+ index(t1 IF_T_IOT_B ) */ a,b,substr(vc,1,40) from t_iot
where b is  null
Plan hash value: 2568267667
--------------------------------------------------------------
| Id  | Operation         | Name       | E-Rows | Cost (%CPU)|
--------------------------------------------------------------
|   0 | SELECT STATEMENT  |            |        |     1 (100)|
|*  1 |  INDEX UNIQUE SCAN| T_IOT_PK   |      1 |     0   (0)|
|*  2 |   INDEX RANGE SCAN| IF_T_IOT_B |      1 |     0   (0)|
--------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access("B" IS NULL)
   2 - access("B" IS NULL)

总结:
IOT的第2索引也不包括NULL值。
				
时间: 2024-07-31 11:08:20

[20121028]IOT的第2索引-NULL的问题.txt的相关文章

[20120608]IOT的第2索引重建.txt

参考链接:http://richardfoote.wordpress.com/2012/05/15/index-rebuild-does-it-use-the-index-or-the-table-nothing-touches-me/ IOT表是特殊的索引结构,如果第2索引的物理猜失败很多,可以通过rebuild来重建索引,修复物理猜失败.很明显第2索引重建的一个目的就是修复物理猜失败,这样要获得正确的UROWID,必须扫描IOT组织表,获得正确的逻辑rowid.但是普通的堆表索引呢?下面看几

[20170516]nvl与非NULL约束2.txt

[20170516]nvl与非NULL约束2.txt --//接着上午的测试看看COALESCE看看过滤的情况. 1.环境: SCOTT@book> @ &r/ver1 PORT_STRING                    VERSION        BANNER ------------------------------ -------------- ----------------------------------------------------------------

[20150803]使用函数索引注意的问题.txt

[20150803]使用函数索引注意的问题.txt --昨天在10g下优化时遇到一个奇怪的问题,做一个记录: --首先说明一下,最近一段时间在做一个项目的优化,这个项目实际上ETL项目: http://baike.baidu.com/link?url=OlbL-2LIVu06toxpf5-PxgekWlOtRgrdwPhGYNx9TgCnCC5WdAGiwOWQXcfUbujcUNwUU6ojdanwP1wSbC_Vf95sgbq7PonHaEZWBVrqkQm ETL,是英文 Extract-

[20170209]索引范围访问2.txt

[20170209]索引范围访问2.txt --ITPUB网友问的问题: http://www.itpub.net/thread-2083504-1-1.html --索引范围扫描是如何访问数据块的? 1 FOR  (根节点-> 分支节点->叶节点->表) 这循环吗? 2 还是(根节点-> 分支节点->叶节点->叶节点->叶节点->叶节点->表)? 3 还是 (根节点-> 分支节点->叶节点->表->叶节点->表->

while ((input = sr.ReadLine()) != null){XXX}读txt,会卡死,求助

问题描述 while((input=sr.ReadLine())!=null){string[]ReadText=input.Replace("","@").Split('@');Global.text.Add(ReadText[0]);Global.text.Add(ReadText[1]);Global.text.Add(ReadText[2]);Global.text.Add(ReadText[3]);Global.text.Add(ReadText[4]);

[20120324]IOT索引组织表相关信息的学习(二).txt

上次链接:http://space.itpub.net/?uid-267265-action-viewspace-itemid-717272 IOT 是一种特殊的索引结构,使用它能够解决特定场合的应用问题,但是在许多应用中很少使用,更多的是使用堆表.我仅仅在生产系统中对3个表使用,我偏向使用静态以及"只读"的小表. 如果IOT表存在除主键外的第2索引,如果使用它存在物理猜"physical guess",我以前的理解一直是第2索引记录了主键信息,通过这个信息就可以定

NULL 值与索引(一)

    NULL值是关系数据库系统布尔型(true,false,unknown)中比较特殊类型的一种值,通常称为UNKNOWN或空值,即是未知的,不确定的.由于NULL存在着无数的可能,因此NULL值也不等于NULL值,所以与NULL值相关的操作同样都为NULL值.正是基于这样一个特性,对于NULL值列上的B树索引导致了is null/is not null不走索引的情形,下面描述了NULL值与索引以及索引NULL列上的执行计划,如何使得NULL值走索引的情形.注:本文仅仅讨论的是B树索引上的N

[20120228]IOT索引组织表相关信息的学习.txt

[20120228]IOT索引组织表相关信息的学习.txt IOT 是一种特殊的索引结构,使用它能够解决特定场合的应用问题,但是在许多应用中很少使用,更多的是使用堆表.我仅仅在生产系统中对3个表使用,我偏向使用静态以及"只读"的小表. 如果IOT表存在除主键外的第2索引,如果使用它存在物理猜"physical guess",我以前的理解一直是第2索引记录了主键信息,通过这个信息就可以定位IOT表中对应的数据,一直没有很好的测试与理解.我最近也看了两个链接,介绍了IO

NULL 值与索引

 NULL 值与索引     NULL值是关系数据库系统布尔型(true,false,unknown)中比较特殊类型的一种值,通常称为UNKNOWN或空值,即是未知的,不确定的.由于 NULL存在着无数的可能,因此NULL值也不等于NULL值,所以与NULL值相关的操作同样都为NULL值.正是基于这样一个特性,对于NULL值列上的B 树索引导致了is null/is not null不走索引的情形,下面描述了NULL值与索引以及索引NULL列上的执行计划,如何使得NULL值走索引的情形. 注:本