[20190706]行记录是否记录了各字段在行位置的起始地址.txt
--//链接http://www.itpub.net/thread-2119080-1-1.html问的问题:
ORACLE 11204
ORACLE 在读取某行记录时,能否快速定位到某字段在该行的位置(行记录上记载了各字段在该行的起始位置,可以快速定位)?
还是说,必须得读取完前面的字段值后,才能读取到该字段值?
比如:id1, id2 ,id3, (id4 CLOB), id5, id6,
我现在需要读取 id5 在某行的值,是不是得把这行记录的 id1 - id4的值都过一遍
(字段值有结束位置,先找id1的结束位置,再找ID2的结束位置,,,),才能读取到id5的值,
还是说,行记录上也记载着 id5 在这行记录上的起始位置,可以快速找到/定位到 id5 的起始位置?
若是后者,对于 CLOB 字段类型,若是几百,上千K,快把一个块占满了,在读取ID5之前,
得不断地寻找ID4的结束位置,那岂不是很耗时间?
--//简单解答一下:
行目录记录偏移位置,是相对偏移.从kdbh算起.
在数据部分记录的格式是,前面还有3个字节(flag,lock,clols(字段数量,如果最后是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> select rowid,emp.* from emp where rownum=1;
ROWID EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
------------------ ---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------
AAAFfZAALAAAACUAAA 7369 SMITH CLERK 7902 1980-12-17 00:00:00 800 20
SCOTT@test01p> @ rowid AAAFfZAALAAAACUAAA
OBJECT FILE BLOCK ROW ROWID_DBA DBA TEXT
---------- ---------- ---------- ---------- -------------------- -------------------- ----------------------------------------
22489 11 148 0 0x2C00094 11,148 alter system dump datafile 11 block 148
--//通过bbed观察:
BBED> set dba 11,149
DBA 0x02c00095 (46137493 11,149)
--//windows下的bbed block存在+1的偏移.
BBED> map
File: D:\APP\ORACLE\ORADATA\TEST\TEST01P\USERS01.DBF (11)
Block: 149 Dba:0x02c00095
------------------------------------------------------------
KTB Data Block (Table/Cluster)
struct kcbh, 20 bytes @0
struct ktbbh, 72 bytes @20
struct kdbh, 14 bytes @100
struct kdbt[1], 4 bytes @114
sb2 kdbr[14] @118
ub1 freespace[7475] @146
ub1 rowdata[567] @7621
ub4 tailchk @8188
--//查看行目录:
BBED> p kdbr
sb2 kdbr[0] @118 8050
sb2 kdbr[1] @120 8007
sb2 kdbr[2] @122 7964
sb2 kdbr[3] @124 7923
sb2 kdbr[4] @126 7878
sb2 kdbr[5] @128 7837
sb2 kdbr[6] @130 7796
sb2 kdbr[7] @132 7756
sb2 kdbr[8] @134 7718
sb2 kdbr[9] @136 7675
sb2 kdbr[10] @138 7637
sb2 kdbr[11] @140 7599
sb2 kdbr[12] @142 7560
sb2 kdbr[13] @144 7521
BBED> x /rnccntnnn *kdbr[0]
rowdata[529] @8150
------------
flag@8150: 0x2c (KDRHFL, KDRHFF, KDRHFH)
lock@8151: 0x01
cols@8152: 8
--//flag,lock,clols,还可以看出1个行片最多255个字段.因为cols仅仅占1个字节.
col 0[3] @8153: 7369
col 1[5] @8157: SMITH
col 2[5] @8163: CLERK
col 3[3] @8169: 7902
col 4[7] @8173: 1980-12-17 00:00:00
col 5[2] @8181: 800
col 6[0] @8184: *NULL*
col 7[2] @8185: 20
--//注意看偏移=8150 ,与实际记录存在100偏移(kdbh位置).
--//注意看NULL.没有长度指示器,实际上仅仅占1个字节0xff表示NULL
BBED> dump offset 8184
File: D:\APP\ORACLE\ORADATA\TEST\TEST01P\USERS01.DBF (11)
Block: 149 Offsets: 8184 to 8191 Dba:0x02c00095
----------------------------------------------------------------------
ff02c115 010604e9
<64 bytes per line>
--//数据部分: 长度+内容+长度+内容+...
--//可以看出如果访问的字段在后面访问"越慢".
--//oracle并不记录了各字段在行位置的起始地址,仅仅在行目录记录开始位置.
--//如果字段字符长度大于250,看链接http://blog.itpub.net/267265/viewspace-2148818/.
--//长度指示器占2个字节.
--//至于lob类型,我不熟悉不探究了.
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/267265/viewspace-2649742/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/267265/viewspace-2649742/