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

简介: [20150929]11g关于行链接.txt --曾经写过block record flag: http://blog.itpub.net/267265/viewspace-1753924/ http://blog.

[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的行变大的情况),会出现行迁移。总之注意这些细节。

目录
相关文章
|
5月前
CSDN生成目录指南
CSDN生成目录指南
43 0
|
10月前
|
Linux Windows
【Linux命令200例】用ln创建链接文件
ln命令是Linux系统中的一个常用命令,用于创建链接文件。链接文件可以理解为指向另一个文件或目录的快捷方式,类似于Windows系统中的快捷方式。在Linux中,链接文件分为两种类型:硬链接(Hard Link)和符号链接(Symbolic Link,也称软链接)。
158 0
|
C#
如何在 C# 项目中链接一个文件夹下的所有文件
在 C# 项目中通过链接方式引入文件可以让我们在项目中使用这些文件中的代码。常见的比如链接 AssemblyInfo.cs 文件,这样我们就可以在项目中使用这个文件中的版本号等信息。但是如果我们想要链接一个文件夹下的所有文件,该怎么做呢?今天我们就来看看如何在 C# 项目中链接一个文件夹下的所有文件。
103 0
如何在 C# 项目中链接一个文件夹下的所有文件
|
Linux Windows
ln命令即链接的制作
ln命令即链接的制作
105 0
ReadMe2.txt 文件内容拷贝 到 新的ReadMe.txt 分析 : 拷贝: 从ReadMe2.txt读取 写入到ReadMe.txt 1.创建两个文
ReadMe2.txt 文件内容拷贝 到 新的ReadMe.txt 分析 : 拷贝: 从ReadMe2.txt读取 写入到ReadMe.txt 1.创建两个文
|
存储
关于链接文件的探讨
跨平台系列汇总:http://www.cnblogs.com/dunitian/p/4822808.html#linux 偶尔在用,其实就是软链接和硬链接两种 软链接 和 win里面的快捷方式差不多,就不多说 探讨下硬链接,有点类似于git的存储方式了,你我各有一份共同修改,你挂了我还有 ...
695 0
|
SQL 算法 C#