您的位置:首页 > 数据库 > Oracle

oracle中的段区块的说明

2016-05-30 01:25 288 查看
段:segment

一个段建立以后,oracle会给它分配一个区,这个区一般是8个块(空块)。

em建立表空间:

创建表空间要考虑的事项有:

1:数据文件个数

2:段的管理方式

          自动:表空间中的对象将自动管理其空闲空间,这将提高空闲空间管理性能(毫无疑问选择自动管理)

          手动:表空间中的对象将使用空闲列表来管理其空闲空间,这是为了确保向后兼容

3:区的管理方式

          本地管理(毫无疑问选择本地管理)

                        选择本地管理后,区的分配方式可以设置为(自动,统一)一般选择自动

          字典管理

4:表空间的状态(读写,只读,脱机)

5:表空间的类型(永久,temp,undo)

6:是否启动事件日志(redolog),一般选择启动。

访问:localhsot:1158/em



登录后进入(管理)->(表空间)-(创建)



创建表空间需要给表空间指定数据文件,在右下角点击(添加)添加数据文件:



点击确定后:



通过em设置后,生成的sql语句为:

CREATE SMALLFILE TABLESPACE "DATA1"

DATAFILE '/u01/app/oracle/oradata/jiagulun/data1_01.dbf' SIZE 100M REUSE

AUTOEXTEND ON NEXT 100M MAXSIZE UNLIMITED

LOGGING

EXTENT MANAGEMENT LOCAL

SEGMENT SPACE MANAGEMENT AUTO

意思为创建表空间名称为:data1

数据文件为:/u01/app/oracle/oradata/jiagulun/data1_01.dbf,数据文件大小为100m,重用数据文件

表空间自动扩展(AUTOEXTEND ON) ,每次扩展大小100M (NEXT 100M) ,最大扩展,不限制(UNLIMITED)

启动redolog(LOGGING)

区管理方式为本地(EXTENT MANAGEMENT LOCAL)

段管理方式为 自动(SEGMENT SPACE MANAGEMENT AUTO)

查询一个段的信息:v$segments;user_tables

select segment_name,blocks,extents,bytes,segment_type,tablespace_name from dba_segments where segment_name = 'T2';



segment_name:段的名称

blocks:有384个块

extents:有18个区

bytes:段大小

segment_type:段类型

tablespace_name:段对应的表空间

blocks和extents和bytes,3个字段的值不是实时的反应段的使用情况的。需要统计分析后才会准确一些。

对表进行分析,使blocks和extents和bytes准确:

analyze table t2 compute statistics 

或者

exec dbms_stats.gather_table_stats('SYS','T2')

查看表的使用情况:

select table_name,num_rows,blocks,empty_blocks,avg_space,chain_cnt,avg_row_len from user_tables where table_name = 'T2'



table_name 表名

num_rows:表有多少行

blocks:表中数据所占的数据块数

empty_blocks:表中的空块数

avg_space:数据块中平均的使用空间(平均每个块908字节)

chain_cnt:表中行连接和行迁移的数量

avg_row_len:每条将记录的平均长度

查看区相关的信息:v$extents 

select * from dba_extents where segment_name = 'T2';



extent_id:是区的编号,上面查询说明了该段分配了0~17编号的区,共18个区

file_id:区所在的文件,上面查询说明了这些区都在1号文件上(dba_data_files)

block_id:起始块id ,上面的查询中0号区的起始块id是61433

blocks:总共块数,上面的查询中0号区的分配了8个块,因为oracle发现分的区太多,oracle会认为你这个段的数据会比较大,所以在第16个区的时候以下就分配了128个块,(这就是区的自动管理,如果是统一管理,那么一直都会是8个块)

高水位线的问题:

     段使用分给他的区的最后一个块的位置,高水位线是oracle对表进行全表扫描的一个位置,(假如段分配了有10万个块,但是实际使用了2000个块,那么高水位线在2000个块的位置,那么如果你访问这个表的时候,oracle只访问2000个块,如果在10个块的位置,那么oracle访问表的时候会访问10万个块。)

通过delete对一个表删除,表的高水位线没有下来(假如有1w个块,当前如果高水位在1000,delete表后,高水位线还会在1000个块的位置)

需要对表进行空间整理

delete from t2;

commit;

analyze table t2 compute statistics;

select table_name,num_rows,blocks,empty_blocks,avg_space,chain_cnt,avg_row_len from user_tables where table_name = 'T2'



查询发现,数据是0行,但是还是占用265个块,那么oracle访问表的时候,会访问265个块。

set autotrace on;

select count(*) from t2;//查看执行计划



通过查询可以看到还是发生了269个读,也就是高水位没有释放

truncate table t2;

commit;

analyze table t2 compute statistics;

select table_name,num_rows,blocks,empty_blocks,avg_space,chain_cnt,avg_row_len from user_tables where table_name = 'T2'



查询看出,blocks已经清空,高水位降了

set autotrace on;

select count(*) from t2;//查看执行计划



发现读几乎没有了

oracle块的物理结构:

     oracle块默认是8k

     块头:块的物理地址,块属于哪个表空间,事务槽,行目录。



如图:块头从上往下用

数据行从下往上用

行的结构:

     行的头部记录行的锁信息,第一列的长度,第一列值,第二列的长度,第二列的列值。。。所有的行都是连在一起的,首尾相连,没个行的长度都是不一样的

oracle读数据块的方式:

在块的头部有行目录,行目录里面将记录了每一行的起始位置。当oracle要找某一行的时候,会在行目录里面找到对应行的起始位置,然后到那个位置去,然后找对应的列,比如要找第三列,那么会先找到第一列的长度,然后跳过第一列的列值,接着找到第二列的长度,再跳过第二列值,就找到了第三列;如果把经常访问的列放在行头部,会有些许的优化,但是效果很小。

查询oracle默认数据块的大小:

show parameter block



可以看到 db_block_size 是8k

查看操作系统的块大小:

dumpe2fs /dev/sda1



block size是4k

也就是说2个操作系统的块是一个oracle的数据块

行连接和行迁移:pct_free

行连接:如果一行的数据太大了超过8k(block默认是8k),那么oracle会用多个块存储1行数据,第一个块指向第二个块,这就是行连接

行迁移:pct_free是一个块剩余空间,当oracle更新数据时原来更新后的数据长度过大,并达到块的pct_free时,这时这个行就不能放到这个块了,那么会启用新的块来放置更新的行,旧块里面的行不会指向新块里面的行。

查看一张表的行连接和行迁移状态:

select table_name,num_rows,blocks,empty_blocks,avg_space,chain_cnt,avg_row_len from user_tables where table_name = 'T2'



chain_cnt就是行连接和行迁移的数量,当avg_row_len大于块的大小时(8k或者查看参数),那么就是行连接,反之则是行迁移,

可以把表导出来再导进去,进行表整理.也可以对这张表建立16k或者32k的表空间.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: