如何根據索引葉塊裡的rowid資訊找到對應的資料行
我們知道索引葉塊中儲存的內容是"被索引的欄位值+rowid",我們如何使用這個rowid找到對應的資料行?
###建立測試用表和索引
col segment_name format a40
col object_name format a40
set linesize 80
select table_name,index_name from dba_indexes where table_name='T1123_1';
TABLE_NAME INDEX_NAME
------------------------------ ------------------------------
T1123_1 IND_T1123_1_OBJID
select object_name,object_id from dba_objects where object_name='IND_T1123_1_OBJID';
OBJECT_NAME OBJECT_ID
---------------------------------------- ----------
IND_T1123_1_OBJID 18924
col name format a30
col value format a70
set linesize 120
select name,value from v$diag_info where name='Default Trace File';
NAME VALUE
------------------------------ ----------------------------------------------------------------------
Default Trace File /u01/app/oracle/diag/rdbms/mydb/mydb/trace/mydb_ora_6498.trc
###dump索引結構
alter session set events 'immediate trace name treedump level 18924';
branch: 0x1c000bb 29360315 (0: nrow: 19, level: 1)
leaf: 0x1c000bc 29360316 (-1: nrow: 481 rrow: 481)
leaf: 0x1c000bd 29360317 (0: nrow: 478 rrow: 478)
leaf: 0x1c000be 29360318 (1: nrow: 478 rrow: 478)
leaf: 0x1c000bf 29360319 (2: nrow: 478 rrow: 478)
leaf: 0x1c000c0 29360320 (3: nrow: 478 rrow: 478)
leaf: 0x1c000c1 29360321 (4: nrow: 478 rrow: 478)
leaf: 0x1c000c2 29360322 (5: nrow: 478 rrow: 478)
leaf: 0x1c000c3 29360323 (6: nrow: 478 rrow: 478)
leaf: 0x1c000c4 29360324 (7: nrow: 478 rrow: 478)
leaf: 0x1c000c5 29360325 (8: nrow: 478 rrow: 478)
leaf: 0x1c000c6 29360326 (9: nrow: 455 rrow: 455)
leaf: 0x1c000c7 29360327 (10: nrow: 448 rrow: 448)
leaf: 0x1c000c9 29360329 (11: nrow: 448 rrow: 448)
leaf: 0x1c000ca 29360330 (12: nrow: 448 rrow: 448)
leaf: 0x1c000cb 29360331 (13: nrow: 448 rrow: 448)
leaf: 0x1c000cc 29360332 (14: nrow: 448 rrow: 448)
leaf: 0x1c000cd 29360333 (15: nrow: 448 rrow: 448)
leaf: 0x1c000ce 29360334 (16: nrow: 448 rrow: 448)
leaf: 0x1c000cf 29360335 (17: nrow: 438 rrow: 438)
選擇其中所在的葉子節點block:29360318做dump
select dbms_utility.data_block_address_file(29360318) fileno,dbms_utility.data_block_address_block(29360318) blkno from dual;
FILENO BLKNO
---------- ----------
7 190
alter system dump datafile 7 block 190;
###mydb_ora_6498.trc內容
header address 140037440318052=0x7f5d01e2aa64
kdxcolev 0
KDXCOLEV Flags = - - -
kdxcolok 0
kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y
kdxconco 2
kdxcosdc 0
kdxconro 478
kdxcofbo 992=0x3e0
kdxcofeo 1818=0x71a
kdxcoavs 826
kdxlespl 0
kdxlende 0
kdxlenxt 29360319=0x1c000bf
kdxleprv 29360317=0x1c000bd
kdxledsz 0
kdxlebksz 8032
row#0[8019] flag: ------, lock: 0, len=13
col 0; len 3; (3): c2 14 18
col 1; len 6; (6): 01 40 00 a5 00 16
row#1[8006] flag: ------, lock: 0, len=13
col 0; len 3; (3): c2 14 1a
col 1; len 6; (6): 01 40 00 a5 00 18
row#2[7993] flag: ------, lock: 0, len=13
col 0; len 3; (3): c2 14 1c
col 1; len 6; (6): 01 40 00 a5 00 1a
row#3[7980] flag: ------, lock: 0, len=13
col 0; len 3; (3): c2 14 1e
col 1; len 6; (6): 01 40 00 a5 00 1c
row#4[7967] flag: ------, lock: 0, len=13
col 0; len 3; (3): c2 14 20
col 1; len 6; (6): 01 40 00 a5 00 1e
row#5[7954] flag: ------, lock: 0, len=13
col 0; len 3; (3): c2 14 22
col 1; len 6; (6): 01 40 00 a5 00 20
row#6[7941] flag: ------, lock: 0, len=13
col 0; len 3; (3): c2 14 24
col 1; len 6; (6): 01 40 00 a5 00 22
。。。省略部分內容
選取其中的row#5,找出鍵值及對應的rowid
鍵值是"c2 14 22"、rowid是"01 40 00 a5 00 20"
###鍵值轉換成實際值
select utl_raw.cast_to_number(replace('c2 14 22',' ')) from dual;
UTL_RAW.CAST_TO_NUMBER(REPLACE('C21422',''))
--------------------------------------------
1933
###從rowid得到relative_fno、block number、row number
"01 40 00 a5 00 20"共6個位元組,48bit,轉換成二進位制是
00000001 01000000 00000000 10100101 00000000 00100000
其中1-10bit代表relative_fno (5)
17-32bit代表block number (165)
33-48bit代表row number (32)
###使用dbms_rowid將object_id=1933這條記錄所在行的rowid進行轉換,以驗證上述結果
select dbms_rowid.rowid_relative_fno(rowid) relative_fno,dbms_rowid.rowid_block_number(rowid) blkno,dbms_rowid.rowid_row_number(rowid) row_number from t1123_1 where object_id=1933;
RELATIVE_FNO BLKNO ROW_NUMBER
------------ ---------- ----------
5 165 32 <---得到的值與我們上一步計算出的結果一致
alter system dump datafile 5 block 165;
tab 0, row 32, @0xb23
tl: 92 fb: --H-FL-- lb: 0x0 cc: 14
col 0: [ 3] 53 59 53
col 1: [22]
56 5f 24 53 54 52 45 41 4d 53 5f 50 4f 4f 4c 5f 41 44 56 49 43 45
col 2: *NULL*
col 3: [ 3] c2 14 22 <---和索引leaf block的儲存的鍵值一致
col 4: *NULL*
col 5: [ 4] 56 49 45 57
col 6: [ 7] 78 74 0a 08 11 23 2c
col 7: [ 7] 78 74 0a 08 11 23 2c
col 8: [19] 32 30 31 36 2d 31 30 2d 30 38 3a 31 36 3a 33 34 3a 34 33
col 9: [ 5] 56 41 4c 49 44
col 10: [ 1] 4e
col 11: [ 1] 4e
col 12: [ 1] 4e
col 13: [ 2] c1 02
需要注意的是索引葉塊裡的rowid資訊,與透過rowid偽列輸出的rowid資訊格式稍有不同,前者使用的是restricted rowid形式,後者使用的是extended rowid格式,較之restricted rowid增加了object number資訊,並且採用了BASE64編碼。
可以透過dbms_rowid這個package裡的函式在extended rowid與object_id、relative_fno、block_number、row_number之間相互轉換:
###extended rowid => object_id、relative_fno、block_number、row_number
SQL> select rowid from t1123_1 where object_id=1933;
ROWID
------------------
AAAEnyAAFAAAAClAAg
set serveroutput on
DECLARE
v_rowid_type NUMBER;
v_OBJECT_NUMBER NUMBER;
v_RELATIVE_FNO NUMBER;
v_BLOCK_NUMBERE_FNO NUMBER;
v_ROW_NUMBER NUMBER;
BEGIN
DBMS_ROWID.rowid_info (rowid_in => 'AAAEnyAAFAAAAClAAg',
rowid_type => v_rowid_type,
object_number => v_OBJECT_NUMBER,
relative_fno => v_RELATIVE_FNO,
block_number => v_BLOCK_NUMBERE_FNO,
ROW_NUMBER => v_ROW_NUMBER);
DBMS_OUTPUT.put_line ('ROWID_TYPE: ' || TO_CHAR (v_rowid_type));
DBMS_OUTPUT.put_line ('OBJECT_NUMBER: ' || TO_CHAR (v_OBJECT_NUMBER));
DBMS_OUTPUT.put_line ('RELATIVE_FNO: ' || TO_CHAR (v_RELATIVE_FNO));
DBMS_OUTPUT.put_line ('BLOCK_NUMBER: ' || TO_CHAR (v_BLOCK_NUMBERE_FNO));
DBMS_OUTPUT.put_line ('ROW_NUMBER: ' || TO_CHAR (v_ROW_NUMBER));
END;
/
ROWID_TYPE: 1
OBJECT_NUMBER: 18930 <---注意這裡是表t1123_1的object_id
RELATIVE_FNO: 5
BLOCK_NUMBER: 165
ROW_NUMBER: 32
###object_id、relative_fno、block_number、row_number => extended rowid
select DBMS_ROWID.ROWID_CREATE(rowid_type=>1,object_number=>18930,relative_fno=>5,block_number=>165,row_number=>32) from dual;
DBMS_ROWID.ROWID_C
------------------
AAAEnyAAFAAAAClAAg
其實還有一種方法可以佐證extended rowid與restricted rowid之間的關係:
將本例中的extended rowid : AAAEnyAAFAAAAClAAg插入一張空表中,然後dump出資料塊
create table t1124_1 (f1 rowid) tablespace st1;
insert into t1124_1 values('AAAEnyAAFAAAAClAAg');
select * from t1124_1;
F1
------------------
AAAEnyAAFAAAAClAAg
select dbms_rowid.rowid_relative_fno(rowid) rfno,dbms_rowid.rowid_block_number(rowid) blkno from t1124_1;
RFNO BLKNO
---------- ----------
7 158
alter system dump datafile 7 block 158;
。。。省略部分內容
block_row_dump:
tab 0, row 0, @0x1f8a
tl: 14 fb: --H-FL-- lb: 0x1 cc: 1
col 0: [10] 00 00 49 f2 01 40 00 a5 00 20
end_of_block_dump
End dump data blocks tsn: 11 file#: 7 minblk 158 maxblk 158
可以看到標註紅色的部分與最初儲存在索引葉塊裡的rowid是一致的(藍色標註的部分表示object number,在restricted rowid裡這部分是沒有的)。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/53956/viewspace-2129002/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 根據rowid查詢資料檔案號,資料塊號
- 根據rowid刪除重複資料
- 根據表查詢索引資訊索引
- oracle ebs 根據請求id找到對應trace 檔案Oracle
- django | 根據 model 建立對應的表Django
- Linux中 awk命令根據列的索引批次提取列的資料Linux索引
- 根據ABAP BAdI definition名稱找到SPRO裡配置路徑的辦法
- Flutter之根據執行的platform顯示對應風格的widgetFlutterPlatform
- 【SQL】根據兩列資訊,整合兩張表資料SQL
- 找到 MySQL 資料庫中的不良索引MySql資料庫索引
- python是如何找到對應的package的?PythonPackage
- Linux 怎麼根據程式號,找對應的程式Linux
- 無法根據TZ_OFFSET的值進行資料訪問
- linux下asm裡如何找到asm disk和os device的對應關係LinuxASMdev
- Xcode如何找到FrameWork對應的原始碼的XCodeFramework原始碼
- IIS7根據PID查詢對應的站點
- mysql根據節點查詢所有葉節點MySql
- 如何根據介面請求型別和請求方法,自動執行對應請求型別
- .NET Core反射獲取帶有自定義特性的類,透過依賴注入根據Attribute後設資料資訊呼叫對應的方法反射依賴注入
- 根據需要的圖表型別選擇echarts對應的series型別型別Echarts
- 如何插入關聯表資料,或插入資料的時候執行,根據某欄位執行一個函式函式
- 大資料時代,如何根據業務選擇合適的分散式框架大資料分散式框架
- 如何根據資料的分佈來選擇ML演算法? - Reddit演算法
- dom4j 根據xml節點路徑查詢節點,找到對應的目標節點下的子節點,對節點Text值進行修改XML
- Shell 根據程式名字找到程式號並kill
- SAP RETAIL 如何根據分配表查到根據它建立的採購訂單?AI
- jquery 根據id去找 json中list的資料jQueryJSON
- 根據條件動態更新不同表的資料
- mysql千萬級資料量根據索引優化查詢速度MySql索引優化
- [golang]-根據json中的某個key的值輸出對應的idGolangJSON
- 索引是一種讓你快速找到資料的資料結構索引資料結構
- 資料庫——對索引的理解資料庫索引
- 獲取演出詳情資料的圖片 url 根據要求組合後重復替換詳情裡的對方 url
- 頭部導航欄也是動態的,板塊裡面的內容根據頭部導航欄動態展現資料
- linux下根據埠號查詢對應程式Linux
- Win10系統如何找到服務對應的程式_Win10找到服務對應的程式的步驟Win10
- 根據連線的資料庫判斷資料庫型別(JAVA)資料庫型別Java
- 根據開源資料庫選擇合適的工具資料庫