[20231024]NULL值在索引的情況.txt
[20231024]NULL值在索引的情況.txt
--//如果全部鍵值是NULL,oracle不儲存該鍵值在索引中.如果表後面幾個欄位是NULL值,oracle不會浪費空間儲存相關資訊.
--//因為在資料塊中存在一個儲存欄位數量的標識,而索引塊不存在這個標識。這樣對於索引欄位最後幾個欄位為NULL的情況,oracle是
--//如何操作的呢? 如果索引尾部幾個欄位是NULL呢?以前沒有關注這個問題,測試看看.
1.環境:
SCOTT@test01p> @ver1
PORT_STRING VERSION BANNER CON_ID
------------------------------ -------------- -------------------------------------------------------------------------------- ----------
IBMPC/WIN_NT64-9.1.0 12.2.0.1.0 Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production 0
2.測試:
SCOTT@test01p> create table empx as select * from emp;
Table created.
SCOTT@test01p> create unique index pk_empx on empx (empno,comm);
Index created.
SCOTT@test01p> select * from empx order by 1;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------
7369 SMITH CLERK 7902 1980-12-17 00:00:00 800 20
7499 ALLEN SALESMAN 7698 1981-02-20 00:00:00 1600 300 30
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7521 WARD SALESMAN 7698 1981-02-22 00:00:00 1250 500 30
7566 JONES MANAGER 7839 1981-04-02 00:00:00 2975 20
7654 MARTIN SALESMAN 7698 1981-09-28 00:00:00 1250 1400 30
7698 BLAKE MANAGER 7839 1981-05-01 00:00:00 2850 30
7782 CLARK MANAGER 7839 1981-06-09 00:00:00 2450 10
7788 SCOTT ANALYST 7566 1987-04-19 00:00:00 3000 20
7839 KING PRESIDENT 1981-11-17 00:00:00 5000 10
7844 TURNER SALESMAN 7698 1981-09-08 00:00:00 1500 0 30
7876 ADAMS CLERK 7788 1987-05-23 00:00:00 1100 20
7900 JAMES CLERK 7698 1981-12-03 00:00:00 950 30
7902 FORD ANALYST 7566 1981-12-03 00:00:00 3000 20
7934 MILLER CLERK 7782 1982-01-23 00:00:00 1300 10
14 rows selected.
--//我按照empno排序,這樣kd_off[2]指向的就是empno的最小鍵值。
SCOTT@test01p> @ seg2 pk_empx
SCOTT@test01p> @ pr
==============================
SEG_MB : 0
SEG_OWNER : SCOTT
SEG_SEGMENT_NAME : PK_EMPX
SEG_PARTITION_NAME :
SEG_SEGMENT_TYPE : INDEX
SEG_TABLESPACE_NAME : USERS
BLOCKS : 8
HDRFIL : 11
HDRBLK : 410
PL/SQL procedure successfully completed.
--//dba =11,411 就是索引的root,empx表僅僅14條記錄,該地址也同時是葉子節點.
3.bbed觀察:
BBED> set dba 11,412
DBA 0x02c0019c (46137756 11,412)
--//windwos bbed版本 塊偏移+1 ,因為無法識別12c的資料檔案OS頭.
BBED> map
File: D:\APP\ORACLE\ORADATA\TEST\TEST01P (11)
Block: 412 Dba:0x02c0019c
------------------------------------------------------------
KTB Data Block (Index Leaf)
struct kcbh, 20 bytes @0
struct ktbbh, 72 bytes @20
struct kdxle, 32 bytes @100
b2 kd_off[14] @132
ub1 freespace[7784] @160
ub1 rowdata[188] @7944
ub4 tailchk @8188
BBED> map
File: D:\APP\ORACLE\ORADATA\TEST\TEST01P (11)
Block: 412 Dba:0x02c0019c
------------------------------------------------------------
KTB Data Block (Index Leaf)
struct kcbh, 20 bytes @0
struct ktbbh, 72 bytes @20
struct kdxle, 32 bytes @100
b2 kd_off[14] @132
ub1 freespace[7805] @160
ub1 rowdata[167] @7965
ub4 tailchk @8188
BBED> p kdxle
struct kdxle, 32 bytes @100
struct kdxlexco, 16 bytes @100
ub1 kdxcolev @100 0x00
ub1 kdxcolok @101 0x00
ub1 kdxcoopc @102 0x80
ub1 kdxconco @103 0x02 --//索引包含2個欄位.如果上面建立的索引非唯 一,這裡是3,
--//包括rowid相關資訊作為索引的一部分
ub4 kdxcosdc @104 0x00000000
sb2 kdxconro @108 14 --//14條記錄.
b2 kdxcofbo @110 64
b2 kdxcofeo @112 7848
b2 kdxcoavs @114 7784
b2 kdxlespl @116 0
sb2 kdxlende @118 0
ub4 kdxlenxt @120 0x00000000
ub4 kdxleprv @124 0x00000000
ub1 kdxledsz @128 0x06 --//索引的rowid在前面,沒有長度指示器,佔6位元組.
--//如果是0,非唯 一索引。是10是全域性唯 一索引。
--//是8是cluster index。
ub1 kdxleunuse @129 0x00
BBED> p kd_off
b2 kd_off[0] @132 8036 --//8036+100(kdxle的偏移)=8136 表示索引的結尾,中間還保留
--//8188-8136 = 52,不知道什麼用處。
b2 kd_off[1] @134 0 --//kd_off[0],kd_off[1]執行的偏移不對,我估計oracle改變了
--//kdxle結構,這4個位元組的內容屬於kdxle。
b2 kd_off[2] @136 8023
b2 kd_off[3] @138 8008
b2 kd_off[4] @140 7993
b2 kd_off[5] @142 7980
b2 kd_off[6] @144 7965
b2 kd_off[7] @146 7952
b2 kd_off[8] @148 7939
b2 kd_off[9] @150 7926
b2 kd_off[10] @152 7913
b2 kd_off[11] @154 7899
b2 kd_off[12] @156 7886
b2 kd_off[13] @158 7874
--//以前提過kd_off指向的鍵值是按照鍵值排序的.注意bbed的版本有問題,實際上從kd_off[2]開始.
BBED> x /rnnn *kd_off[2]
rowdata[179] @8123
------------
flag@8123: 0x00 (NONE)
lock@8124: 0x00
keydata[6]: 0x02 0xc0 0x01 0x93 0x00 0x00
data key:
col 0[3] @8132: 7369
col 1[0] @8136: *NULL*
--//8123+1+1+6+1+3+1 = 8136
--//8188-8136 = 52,確實保留52位元組在資料塊尾部,為什麼?
BBED> x /rnnn *kd_off[3]
rowdata[164] @8108
------------
flag@8108: 0x00 (NONE)
lock@8109: 0x00
keydata[6]: 0x02 0xc0 0x01 0x93 0x00 0x01
data key:
col 0[3] @8117: 7499
col 1[2] @8121: 300
--//選擇16進位制看看.
BBED> x /rxxx *kd_off[2]
rowdata[179] @8123
------------
flag@8123: 0x00 (NONE)
lock@8124: 0x00
keydata[6]: 0x02 0xc0 0x01 0x93 0x00 0x00
data key:
col 0[3] @8132: 0xc2 0x4a 0x46
col 1[0] @8136: *NULL*
BBED> p tailchk
ub4 tailchk @8188 0xb5370601
BBED> dump /v offset 8123 count 100
File: D:\APP\ORACLE\ORADATA\TEST\TEST01P\USERS01.DBF (11)
Block: 412 Offsets: 8123 to 8191 Dba:0x02c0019c
-------------------------------------------------------
000002c0 01930000 03c24a46 ff000000 l ...?....翵F....
00000000 00000000 00000000 00000000 l ................
00000000 00000000 00000000 00000000 l ................
00000000 00000000 00000000 00000000 l ................
00010637 b5 l ...7
<16 bytes per line>
BBED> dump /v offset 8123 count 13
File: D:\APP\ORACLE\ORADATA\TEST\TEST01P\USERS01.DBF (11)
Block: 412 Offsets: 8123 to 8135 Dba:0x02c0019c
-------------------------------------------------------
000002c0 01930000 03c24a46 ff l ...?....翵F.
<16 bytes per line>
--//可以發現NULL儲存的資訊0xff,前面沒有長度指示器。有點奇怪為什麼索引在底部保留一段沒有儲存資訊,佔用52位元組.
BBED> x /rxxx *kd_off[5]
rowdata[136] @8080
------------
flag@8080: 0x00 (NONE)
lock@8081: 0x00
keydata[6]: 0x02 0xc0 0x01 0x93 0x00 0x03
data key:
col 0[3] @8089: 0xc2 0x4c 0x43
col 1[0] @8093: *NULL*
BBED> dump /v offset 8080 count 13
File: D:\APP\ORACLE\ORADATA\TEST\TEST01P\USERS01.DBF (11)
Block: 412 Offsets: 8080 to 8092 Dba:0x02c0019c
-------------------------------------------------------
000002c0 01930003 03c24c43 ff l ...?....翷C.
<16 bytes per line>
--//也就是索引是保留NULL值的,即使在索引欄位的尾部。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-2991953/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- NULL 值與索引Null索引
- 關於NULL值在索引裡的兩個疑惑Null索引
- NULL 值與索引(二)Null索引
- mysql索引失效的情況MySql索引
- MySQL分割槽, 子分割槽以及對錄入Null值的處理情況MySqlNull
- ORACLE索引被抑制情況Oracle索引
- mysql索引不會命中的情況MySql索引
- oracle order by索引是否使用的情況Oracle索引
- 索引裡的NULL值與排序小記索引Null排序
- MySQL哪些情況需要新增索引?MySql索引
- Mysql 會導致索引失效的情況MySql索引
- MYSQL索引失效的各種情況小結MySql索引
- [zt] Oracle不使用索引的幾種情況Oracle索引
- MySQL null值欄位是否使用索引的總結MySqlNull索引
- SQL優化--強制走索引失效的情況SQL優化索引
- NULL在oracle和mysql索引上的區別NullOracleMySql索引
- 唯一索引,可以在索引列插入多個null嗎索引Null
- Oracle 12.2中的索引統計被呼叫情況Oracle索引
- 簡單介紹MySQL索引失效的幾種情況MySql索引
- 淺談索引序列之是否可以儲存NULL值?索引Null
- oracle組合索引什麼情況下生效?Oracle索引
- js中bool值為false的幾種情況JSFalse
- java查詢資料庫,int型欄位為null的情況Java資料庫Null
- [20121028]IOT的第2索引-NULL的問題.txt索引Null
- 在oracle中監視索引的使用情況Oracle索引
- 在不重灌Windows情況Ç(轉)Windows
- NULL與索引Null索引
- oracle 為什麼沒有使用索引的一種情況Oracle索引
- [20200219]strace跟蹤設定ENABLE=BROKEN的情況(網路的情況).txt
- 關於變數與‘=’賦值的情況出錯變數賦值
- 【NULL】Oracle null值介紹NullOracle
- ORACLE MYSQL中join 欄位型別不同索引失效的情況OracleMySql型別索引
- Oracle like、不等於、隱式轉換走索引與不走索引情況Oracle索引
- 論壇藉助:最佳化sql,null值如何走索引SQLNull索引
- 測試在cursor_sharing為force情況下執行計劃的共享情況
- hive中的null值HiveNull
- MySQL中IS NULL、IS NOT NULL、!=不能用索引?胡扯!MySqlNull索引
- 索引與null(一):單列索引索引Null