[20150929]11g关于行链接.txt

[20150929]11g关于行链接.txt

--曾经写过block record flag:
http://blog.itpub.net/267265/viewspace-1753924/
http://blog.itpub.net/267265/viewspace-1753933/

--总结如下:
#define KDRHFK 0x80 Cluster Key                                    =>使用K表示
#define KDRHFC 0x40 Clustered table member                         =>使用C表示
#define KDRHFH 0x20 Head piece of row                              =>使用H表示
#define KDRHFD 0x10 Deleted row                                    =>使用D表示
#define KDRHFF 0x08 First data piece                               =>使用F表示
#define KDRHFL 0x04 Last data piece                                =>使用L表示
#define KDRHFP 0x02 First column continues from Previous piece     =>使用P表示
#define KDRHFN 0x01 Last column continues in Next piece            =>使用N表示

--提到
#define KDRHFP 0x02 First column continues from Previous piece
#define KDRHFN 0x01 Last column continues in Next piece         

--最后2个表示在8k的数据块应该很难看到,不过问一下别人8i,9i好像看到过。
--实际上信息跨2个或者多个数据块,我演示使用2k的数据块。这样1个数据块放不下4000个字节的字段,才出现那2个flag。
--昨天被别人问及这个问题,不管怎样我在11g下没有看到这2个flag在8k的数据块的情况下出现,在11G下做一个例子:

1.建立环境:
SCOTT@test> @ver1

PORT_STRING                    VERSION        BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx            11.2.0.3.0     Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production

create table t ( id number,col1 varchar2(4000), col2 varchar2(4000), col3 varchar2(4000));
insert into t values (1,lpad('1', 4000, '1'), lpad('2', 4000, '2'), lpad('3', 4000, '3'));
commit ;

SCOTT@test> select rowid from t;

ROWID
------------------
AABNUUAAEAAAACkAAA

SCOTT@test> @rowid AABNUUAAEAAAACkAAA
    OBJECT       FILE      BLOCK        ROW DBA                  TEXT
---------- ---------- ---------- ---------- -------------------- ----------------------------------------
    316692          4        164          0 4,164                alter system dump datafile 4 block 164 ;

SCOTT@test> alter system checkpoint;
System altered.
   
2.使用bbed观察:
--注实际上使用转储也可以查看,我喜欢使用bbed观察,这样更加快以及直观一些。

BBED> set dba 4,164
        DBA             0x010000a4 (16777380 4,164)

BBED> p *kdbr[0]
rowdata[0]
----------
ub1 rowdata[0]                              @4173     0x28

BBED> x /rnccc
rowdata[0]                                  @4173
----------
flag@4173: 0x28 (KDRHFF, KDRHFH)
lock@4174: 0x01
cols@4175:    2
nrid@4176:0x010000a7.0

col    0[2] @4182: 1
col 1[4000] @4185: 1111111111111111111111111111111111111111111....

--继续看链接的数据块情况:
BBED> set dba 0x010000a7
        DBA             0x010000a7 (16777383 4,167)

BBED> p *kdbr[0]
rowdata[0]
----------
ub1 rowdata[0]                              @4176     0x00

BBED> x /rccc
rowdata[0]                                  @4176
----------
flag@4176: 0x00 (NONE)
lock@4177: 0x01
cols@4178:    1
nrid@4179:0x010000a3.0

col 0[4000] @4185: 2222222222222222222222222222222222222222222....

--继续看链接的数据块情况:
BBED> set dba 0x010000a3
        DBA             0x010000a3 (16777379 4,163)

BBED> p *kdbr[0]
rowdata[0]
----------
ub1 rowdata[0]                              @4182     0x04

BBED> x /rccc
rowdata[0]                                  @4182
----------
flag@4182: 0x04 (KDRHFL)
lock@4183: 0x01
cols@4184:    1

col 0[4000] @4185: 33333333333333333333333333333333333333333333333

-- 对照上面发现:
#define KDRHFK 0x80 Cluster Key                                    =>使用K表示
#define KDRHFC 0x40 Clustered table member                         =>使用C表示
#define KDRHFH 0x20 Head piece of row                              =>使用H表示
#define KDRHFD 0x10 Deleted row                                    =>使用D表示
#define KDRHFF 0x08 First data piece                               =>使用F表示
#define KDRHFL 0x04 Last data piece                                =>使用L表示
#define KDRHFP 0x02 First column continues from Previous piece     =>使用P表示
#define KDRHFN 0x01 Last column continues in Next piece            =>使用N表示

flag@4173: 0x28 (KDRHFF, KDRHFH) => dba 4,164   0x28 Head piece of row+First data piece
flag@4176: 0x00 (NONE)           => dba 4,167   0x00
flag@4182: 0x04 (KDRHFL)         => dba 4,163   0x04 Last data piece

--依旧没有看到
#define KDRHFP 0x02 First column continues from Previous piece
#define KDRHFN 0x01 Last column continues in Next piece         

--很明显这3个字段colx分布在3个块,并且每个字段并没有被拆开。这样情况下通过索引访问逻辑读比一般的情况下多1到2个逻辑读。

3.建立索引测试:

SCOTT@test> create unique index pk_t on t(id);
Index created.

SCOTT@test> alter session set statistics_level=all;
Session altered.

SCOTT@test> select * from t where id=1;
...

SCOTT@test> @dpcz ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  07hpk6hpb7pp8, child number 0
-------------------------------------
select * from t where id=1
Plan hash value: 2454218153
------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |
------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |      |      1 |        |       |     1 (100)|          |      1 |00:00:00.01 |       4 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T    |      1 |      1 |  6019 |     1   (0)| 00:00:01 |      1 |00:00:00.01 |       4 |
|*  2 |   INDEX UNIQUE SCAN         | PK_T |      1 |      1 |       |     0   (0)|          |      1 |00:00:00.01 |       1 |
------------------------------------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
   1 - SEL$1 / T@SEL$1
   2 - SEL$1 / T@SEL$1
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("ID"=1)
25 rows selected.

4.继续通过例子来说明问题:
--建立表t1:
create table t1 ( id number,col1 varchar2(1000), col2 varchar2(1000), col3 varchar2(1000),col4 varchar2(1000));
insert into t1 select rownum ,lpad('1', 1000, '1'), lpad('2', 1000, '2'), lpad('3', 1000, '3'),lpad('4', 1000, '4') from dual connect by level<=100;
commit ;

SCOTT@test> select distinct substr(rowid,-3,3) from t1;
SUBSTR
------
AAA

--substr(rowid,-3,3)表示取rowid最后3个字符,可以发现都是'AAA',也就是行号都是0,也就是讲每块1条记录。

SCOTT@test> select rowid from t1 where rownum=1;
ROWID
------------------
AABNVqAAEAAAAIbAAA

SCOTT@test> @rowid AABNVqAAEAAAAIbAAA
    OBJECT       FILE      BLOCK        ROW DBA                  TEXT
---------- ---------- ---------- ---------- -------------------- ----------------------------------------
    316778          4        539          0 4,539                alter system dump datafile 4 block 539 ;

SCOTT@test> alter system checkpoint;
System altered.

BBED> set dba 4,539
        DBA             0x0100021b (16777755 4,539)

BBED> map
File: /u01/app/oracle11g/oradata/test/users01.dbf (4)
Block: 539                                   Dba:0x0100021b
------------------------------------------------------------
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[1]                                @118
ub1 freespace[4050]                        @120
ub1 rowdata[4018]                          @4170
ub4 tailchk                                @8188

--可以发现freespace=4050, 4050/8000=.50625,剩余接近50%的空间被浪费了。像这种情况最好使用更大的数据块,但是这样有带来管理
--上的麻烦,要合理设置参数,总之在数据库设计上注意这些问题,如果行接近4K的情况下,最好选择更大的数据块,合理设置参数避免
--空间的浪费.

--补充测试,如果设置pctfree=0:

create table t1 ( id number,col1 varchar2(1000), col2 varchar2(1000), col3 varchar2(1000),col4 varchar2(1000)) pctfree 0;
insert into t1 select rownum ,lpad('1', 1000, '1'), lpad('2', 1000, '2'), lpad('3', 1000, '3'),lpad('4', 1000, '4') from dual connect by level<=100;
commit ;

SCOTT@test> select count( substr(rowid,-3,3)),substr(rowid,-3,3) from t1 group by substr(rowid,-3,3);
COUNT(SUBSTR(ROWID,-3,3)) SUBSTR
------------------------- ------
                       50 AAA
                       50 AAB

--这样空间利用率最高,但是如果表存在一些dml(update的行变大的情况),会出现行迁移。总之注意这些细节。

时间: 2024-09-20 12:42:29

[20150929]11g关于行链接.txt的相关文章

[20160726]行链接行迁移与ITL槽.txt

[20160726]行链接行迁移与ITL槽.txt 当表中一行的数据不能在一个数据block中放入的时候,这个时候就会发生两种情况,一种是行链接(Row Chaining),另外一种就是行迁 移(Row Migration)了. 行链接产生在第一次插入数据的时候如果一个block不能存放一行记录的情况下.这种情况下,Oracle将使用链接一个或者多个在这个段 中保留的block存储这一行记录,行链接比较容易发生在比较大的行上,例如行上有LONG.LONG RAW.LOB等数据类型的字段,这种时候

[20160728]]行链接行迁移与ITL槽3.txt

[20160728]]行链接行迁移与ITL槽3.txt --上午测试了行链接行迁移与ITL槽的关系,链接如下: [20160727]行链接行迁移与ITL槽2.txt => http://blog.itpub.net/267265/viewspace-2122663/ --如果仔细看前面的测试可以发现当出现行链接或者行迁移时,除了增加1个空itl槽像如下: 0x05   0x0000.000.00000000  0x00000000.0000.00  C---    0  scn 0x0000.0

[20160729]行链接行迁移与ITL槽4.txt

[20160729]行链接行迁移与ITL槽4.txt --做了几个测试,有点乱. http://blog.itpub.net/267265/viewspace-2122700/ http://blog.itpub.net/267265/viewspace-2122663/ http://blog.itpub.net/267265/viewspace-2122599/ --还是通过1个例子来模拟看看.做一个非常极端的测试: 1.环境: SCOTT@book> @ &r/ver1 PORT_ST

[20121116]通过bbed观察行链接与行迁移.txt

[20121116]通过bbed观察行链接与行迁移.txt     如果应用中出现大量的行链接与行迁移,对应用的性能多少存在影响.一般情况下,行迁移主要是update后,行记录变大,导致原来的数据块无法容纳,在原来的块保留指针,其他信息放在其他块中.而行链接主要是行记录太大,1个数据块无法容纳,导致使用多块保存.我想通过bbed简单观察这种情况: 1.建立测试环境: SQL> select * from v$version where rownum BANNER ----------------

[20160803]另类行迁移.txt

[20160803]另类行迁移.txt --前几天做测试时,链接: http://blog.itpub.net/267265/viewspace-2122712/=>[20160729]行链接行迁移与ITL槽4.txt --发现一个块中的记录在字段长度变长后全部发生行迁移,感觉很奇怪,当时也没有仔细思考(开始以为至少有一些记录不会发生行迁移的 --情况),事后才想起来以前我做过类似的测试,参考链接: http://blog.itpub.net/267265/viewspace-1742243/=

[20140213]再论行迁移.txt

[20140213]再论行迁移.txt 昨天看jonathanlewis的blog,链接如下: https://jonathanlewis.wordpress.com/2014/02/10/row-migration/ Oracle behaves quite intelligently with migrated rows. First, the migrated row has a pointer back to the original location and if the row ha

[20170516]11G use_large_pages参数2.txt

[20170516]11G use_large_pages参数2.txt //前面我提到如果设置use_large_pages=auto.设置页面大小不足时,oracle会oradism经常修改内核参数vm.nr_hugepages. //忘记测试是否在退出后可以收回.链接如下: http://blog.itpub.net/267265/viewspace-2135210/ --//不知道什么回事,以前写的,忘记发了,补上. 1.环境 SYS@book> @ &r/ver1 PORT_STR

[20170207]11G审计日志清除.txt

[20170207]11G审计日志清除.txt --//11G缺省打开了许多审计,比如登录审计(我个人建议仅仅审计不成功的登录,特别对登录密集的系统),如果系统上线时没有关闭或者取 --//消一些审计,sys.aud$在system表空间,会导致空间异常增加,而且占用system表空间不是很合理.必须建立良好的监测清理机制. 1.环境: SCOTT@book> @ &r/ver1 PORT_STRING                    VERSION        BANNER ---

[20160911]windows下建立硬链接.txt

[20160911]windows下建立硬链接.txt --大家知道linux ln命令可以建立硬连接或者软连接.参考: http://blog.itpub.net/267265/viewspace-1812272/ --实际上windows下也有类似ln命令,只不过许多人很少在命令行使用windows,对于里面的命令行命令知道的更少. --通过例子说明,使用fsutil就可以建立硬连接.补充一点建立这种硬连接仅仅支持NTFS文件系统,不要指望支持FAT32. --实际上这个测试,主要有用户需求