四 块(block) Ø 概述 ·是一个或一组连续的os块,大小是os块的整数倍(8k、512B) ·是数据库中粒度最小的数据组织单位与管理单位 ·是数据文件disk存储空间单位,也是数据库I/O的最小单位 ·数据块大小由db_block_size参数决定,默认8k ·9i以前只能设定一种块大小,9i/10g中不同表空间可指定不同的块大小 Ø 块结构 块头: 块概要信息,包括块地址,段类型等 表目录: 在该块中存储了数据行动表的表信息 行目录: 存储在该块中的数据行的行信息 空闲区: 用于插入新行和需要额外空间的行更新 行数据: 存储在该块中山数据行的具体内容 块参数pctfree,pctused pctfree(默认值10) 当向一个空数据块插入的数据量达到该数据块大小1-pctfree时,即停止对该块进行插入(剩余空间留给update跟新使用),而再分配另一新数据块进行插入,并将该块从空闲块列表freelist中移除。 经常进行update的表应将pctfree调高,则跟新时尽量保证跟新数据仍位于原数据块中,避免发生行迁移或行链接。因为update操作会消耗掉空闲空间,当一个块中的空闲因为太小而不够update操作消耗的话,系统就会增加新块,从而形成记录链接或行迁移影响表达I/O功能。 pctused(默认值40) 当数据块内数据被删除到pctused所指定点值时,即将该块移入空闲列表freelist中,使其可以接受新数据段插入。 经常进行delete的表应将pctused调高,以便能有效利用空间,因为一个pctused值较高的数据块,其中能存放的数据将更多。该参数和pctfree配合使用,pctused越大越有利于insert,pctfree越大越有利于update。两参数加起来不能超过100. 行迁移:一行记录初始插入时可以存储在一个块中,但因后来更新导致行长增加,而块的自由空间已经完全满脸,此时产生行迁移,将整行的数据迁移到一个新的数据块上。而将该行原先的空间只放一个指针,指向该行的新的位置。 行链接:当第一个插入数据时一个块就不能存下一行记录的情况下,系统将使用链接在多个块中存储该记录。 测试: SQL> create table t3(x int,y varchar2(200)) pctfree 0; SQL> create table t4(x int,y varchar2(200)) pctfree 20; SQL> begin 2 for I in 1..4000 3 loop 4 insert into t3 values (I,'aaaaaaaaaa'); 5 insert into t4 values (I,'aaaaaaaaaa'); 6 end loop; 7 commit; 8 end; 9 / SQL> select extent_id,blocks,block_id from dba_extents where segment_name='T3'; EXTENT_ID BLOCKS BLOCK_ID ---------- ---------- ---------- 0 8 61153 1 8 61177 SQL> select extent_id,blocks,block_id from dba_extents where segment_name='T4'; EXTENT_ID BLOCKS BLOCK_ID ---------- ---------- ---------- 0 8 61161 1 8 61169 SQL> analyze table t3 compute statistics; SQL> analyze table t4 compute statistics; SQL> select chain_cnt from dba_tables where table_name='T3'; CHAIN_CNT ---------- 0 SQL> select chain_cnt from dba_tables where table_name='T4'; CHAIN_CNT ---------- 0 SQL> update t3 set y='aaaaaaaaaaa'; SQL> update t4 set y='aaaaaaaaaaa'; SQL> commit; SQL> analyze table t3 compute statistics; SQL> analyze table t4 compute statistics; SQL> select chain_cnt from dba_tables where table_name='T3'; 行链接或行迁移 CHAIN_CNT ---------- 402 SQL> select chain_cnt from dba_tables where table_name='T4'; CHAIN_CNT ---------- 0 SQL> select tablespace_name,segment_space_management from dba_tablespaces; 查询表空间的段空间管理方式,ASSM方式下建立的表将忽略pct_used参数。 SQL> create table test1 (id char(2));使用系统默认pctfree/pctused参数 SQL> create table test2 (id char(2)) pctfree 20 pctused 50 tablespace system; MSSM段空间管理方式中指定表的pctfree/pctused值 SQL> create table test3 (id char(2)) pctfree 20 pctused 50 tablespace users; ASSM段空间管理方式中指定表的pctfree/pctused值 SQL> select table_name,pct_free,pct_used from user_tables where table_name in ('TEST1','TEST2','TEST3'); TABLE_NAME PCT_FREE PCT_USED ------------------------------ ---------- ---------- TEST1 10 40 TEST2 20 50 TEST3 20 查询表的pct_free和pctused值 Free list&free group 在segment中,若同一时刻发生多个insert,将引起free list争用,故一个segment中一般存在多个free list。free list的多少决定了同一时刻可以在同一segment中进行insert操作的数量。多个free list又可归属于不同的free list group。 SQL> create table t5(a int,b char(16)); SQL> select substr(segment_name,1,8),freelists,freelist_groups from dba_segments where segment_name='T5'; SUBSTR(SEGMENT_N FREELISTS FREELIST_GROUPS ---------------- ---------- --------------- T5 1 1 SQL> alter table t5 storage (freelists 5); SQL> select substr(segment_name,1,8),freelists,freelist_groups from dba_segments where segment_name='T5'; SUBSTR(SEGMENT_N FREELISTS FREELIST_GROUPS ---------------- ---------- --------------- T5 5 1 SQL> create table t6 (a int,b char(16)) storage (freelists 4 freelist groups 2); SQL> select substr(segment_name,1,8),freelists,freelist_groups from dba_segments where segment_name='T6'; SUBSTR(SEGMENT_N FREELISTS FREELIST_GROUPS ---------------- ---------- --------------- T6 4 2 当freelist group=1时,freelist都存储在segment header(第一个块)内,真正数据段存储就从第2块开始,当freelist group>1时,freelist从segment header内分离出来,存储在单独的块里面,每个freelistgroup占一个block,即真正数据段存储就从 1(for segment header)+n(free list group数量)块之后的块开始。 转载请保留固定链接: https://linuxeye.com/database/666.html |