行迁移、行链接
实验目的:了解、查询、处理行迁移、行链接的情况
1..解释说明:块、行迁移、行链接、视图、analyze命令、查询
2,0实验思路:
2.1:行链接
2.2:测试出一个行链接的数据
2.3:发生行链接,有什么好的方法
2.4:行迁移
2.5:测试出一个行迁移的数据
2.6:发生行迁移,有什么好的方法
1.解释说明:块、行迁移、行链接、视图、analyze命令、查询
1.1:块的空间说明:
块:分三个区域:块头部、可用空间、预留空间
#视图结构信息:
SQL> desc chained_rows; Name Null? Type ----------------------------------------- -------- ---------------------------- OWNER_NAME 表的用户
TABLE_NAME 表名称 CLUSTER_NAME PARTITION_NAME 分区名称 SUBPARTITION_NAME 子分区名称 HEAD_ROWID 链接行 rowid ANALYZE_TIMESTAMP 使用analyze分析时间
SQL> select OWNER,OBJECT_NAME,OBJECT_TYPE from dba_objects where owner='SYS'
and object_name='CHAINED_ROWS';
OWNER OBJECT_NAME OBJECT_TYPE
-----------------------------------------------------------------------------
SYS CHAINED_ROWS TABLE
1.5:analyze 收集表结构统计信息:
未收集user_tables很多信息缺失,无法查询
命令: analyze table xx compute statistics;
命令: analyze table xx LIST CHAINED ROWS INTO chained_rows;
2,0实验思路:
2.1:测试出一个行迁移的数据
2.2:行迁移带来的问题:
2.3:发生行迁移,有什么好的方法
2.4:测试出一个行链接的数据
2.2:行链接带来的问题:
2.3:发生行链接,有什么好的方法
#创建一个对象表:
SQL> create table row_a(id char(1500),name char(2000),city varchar2(2000));
#Insert测试数据:两行数据:7000多个字节
SQL> insert into row_a values(1,'yang','beijing');
SQL> insert into row_a values(2,'cheng','hukou');
SQL> commit;
#收集表的结构信息
SQL> analyze table row_a compute statistics;
#查询表的平均行长度
SQL> select table_name,avg_row_len from user_tables where table_name='ROW_A';
TABLE_NAME AVG_ROW_LEN
------------------------------ -----------
ROW_A 3516
#查询表的rowid
SQL> select rowid from row_a order by 1;
ROWID
------------------
AAADzKAAFAAAADsAAA
AAADzKAAFAAAADsAAB
#第一次Update
SQL> update row_a set city=(select name from row_a where id=2) where id=2;
#分析
SQL> analyze table song.row_a list chained rows;
#ROWID不变:
SQL> select rowid from row_a order by 1;
AAADzKAAFAAAADsAAA
AAADzKAAFAAAADsAAB
#查询视图:未发现记录
select * from chained_rows
no rows selected
#第二次UPDATE
SQL> update row_a set city=(select name from row_a where id=2) where id=1;
SQL> commit;
#ROWID不变:
SQL> select rowid from row_a order by 1;
AAADzKAAFAAAADsAAA
AAADzKAAFAAAADsAAB
#查询视图:第二行数据:发生了行迁移
select * from chained_rows
SONG ROW_A N/A AAADzKAAFAAAADsAAB 07-APR-18
#通过Rowid查询:都在一个块中
select rowid from row_a
ROWID
------------------
AAADzKAAFAAAADsAAA
AAADzKAAFAAAADsAAB
#查询结果7次逻辑读:读取这两行记录:读取了两个块,原本只需要一个块,会最少多一次逻辑读
SQL> set autotrace traceonly; SQL> select * from row_a; 7 consistent gets
#此处有系统的调用,为了更好的对比此次实验:
创建一个新表,一条数据,查询对比
create table c(id int);
insert into c(1);
commit;
SQL> analyze table c compute statistics;
set autotrace traceonly;
select * from c;
6 consistent gets
2.3:发生了行迁移:如何更好的处理:
=> 修改Block中的Pctfree值,设置减少,增加块中预留update的空间
SQL> select table_name,PCT_FREE from user_tables where table_name='ROW_A'; TABLE_NAME PCT_FREE ------------------------------ ---------- ROW_A 10 SQL> alter table row_a pctfree 20; Table altered. SQL> select table_name,PCT_FREE from user_tables where table_name='ROW_A'; TABLE_NAME PCT_FREE ------------------------------ ---------- ROW_A 20 #以上是为了如何避免: #以下是如何解决此次: SQL> alter table row_a move; #通过rowid可以判断,两行数据,使用的不同的块 SQL> select rowid from row_a; ROWID ------------------ AAADzNAAFAAAADrAAA AAADzNAAFAAAADsAAA #查询视图: 记录还保留:问题其实已经解决 SQL> select * from chained_rows; SONG ROW_A N/A AAADzKAAFAAAADsAAB 07-APR-18
2.4:测试出一个行链接的数据
SQL> create table t_row_chaining(a char(2000),b char(2000),c char(2000),d char(2000)); SQL> insert into t_row_chaining values('x','y','z','a'); SQL> commit;
#分析表:将行链接、行迁移记录插入 chainde_rows
SQL> analyze table song.t_row_chaining list chained rows into chained_rows;
SQL> select * from chained_rows;
SONG T_ROW_CHAINING
N/A AAADzOAAFAAAAD9AAA 07-APR-18
2.5:行链接可能带来的性能问题:
#通过Rowid查询:都在一个块中
select rowid from T_ROW_CHAINING;
ROWID
------------------
AAADzOAAFAAAAD9AAA
SQL> set autotrace traceonly
SQL> select * from T_ROW_CHAINING;
8 consistent gets #至少多读一个块
#此处有系统的调用,为了更好的对比此次实验:
创建一个新表,一条数据,查询对比
create table c(id int);
insert into c(1); commit;
SQL> analyze table c compute statistics;
set autotrace traceonly;
select * from c;
6 consistent gets
2.6:发生行链接,有什么好的方法
=>使用非标准:大的数据块的数据文件:对应缓冲区,也需要有足够的buffer_size与之对应
#创建一个16K块大小的表空间 SQL> create tablespace block_16 datafile '/picclife/app/oracle/oradata/dingding/bk16.dbf' size 20m blocksize 16k; #指定cache缓冲区:非标准块大小 SQL> alter system set db_16k_cache_size=20m; =>MOVE移动表到大块的表空间内
【如果不使用大块表空间存储,即使Move,由于单行数据大于一个块的存储还是会发生行链接】 alter table song.t_row_chaining move tablespace block_16; 分析: analyze table song.t_row_chaining list chained rows; #再次查询:ROWID发生改变 SQL> select rowid from song.t_row_chaining; ROWID ------------------ AAADzSAAGAAAABDAAA #查询表中的ROWID在:行迁移、行链接中的 数据 SQL> select * from chained_rows where HEAD_ROWID=(select rowid from song.t_row_chaining); no rows selected