您的位置:首页 > 数据库

10、管理数据库存储(行迁移及行连接)

2017-05-30 13:41 435 查看
管理数据库存储
1block=8192bytes

案例1:行迁移

1、表中数据如何存储
create table test as select * from hr.employees;
create index idx_test on test(employee_id);
只看执行计划,不执行结果。
set autotrace traceonly statistics;
select * from test where employee_id>0;

强制走索引
select /*+index(test,idx_test_id) */ * from test where employee_id>0;

SQL> select /*+index(test,idx_test_id) */ * from test where employee_id>0;

107 rows selected.

Statistics
----------------------------------------------------------
7 recursive calls
0 db block gets
19 consistent gets
0 physical reads
0 redo size
9096 bytes sent via SQL*Net to client
601 bytes received via SQL*Net from client
9 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
107 rows processed

解读:19 consistent gets 需要19个block才能存107行数据

set autotrace off;
alter table test modify FIRST_NAME varchar2(1000);
alter table test modify LAST_NAME varchar2(1000);
alter table test modify EMAIL varchar2(1000);
alter table test modify PHONE_NUMBER varchar2(1000);

update test set LAST_NAME=lpad(LAST_NAME,1000,'*'),FIRST_NAME=lpad(FIRST_NAME,1000,'*'),EMAIL=lpad(EMAIL,1000,'*'),PHONE_NUMBER=lpad(PHONE_NUMBER,1000,'*');

SQL> set autotrace traceonly statistics;
SQL> select /*+index(test,idx_test_id) */ * from test where employee_id>0;

107 rows selected.

Statistics
----------------------------------------------------------
9 recursive calls
0 db block gets
288 consistent gets
0 physical reads
0 redo size
438255 bytes sent via SQL*Net to client
601 bytes received via SQL*Net from client
9 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
107 rows processed

SQL> set autotrace off;

SQL> @/u01/app/oracle/product/11.2.0/db_1/rdbms/admin/utlchain.sql

Table created.
其中表结构为:
create table CHAINED_ROWS (
owner_name varchar2(30),
table_name varchar2(30),
cluster_name varchar2(30),
partition_name varchar2(30),
subpartition_name varchar2(30),
head_rowid rowid,
analyze_timestamp date
);

把test表行行迁移信息放到这张表 CHAINED_ROWS 中
analyze table test list chained rows into CHAINED_ROWS;

select table_name,count(*) from CHAINED_ROWS group by table_name;

SQL> select table_name,count(*) from CHAINED_ROWS group by table_name;

TABLE_NAME COUNT(*)
------------------------------ ----------
TEST 105

这里表示 TEST 表有107行数据,其中105行数据搬家了。发生了行迁移。

如何消除行迁移???
1、把发生行迁移的行放到一个临时表中
create table test_temp as select * from test where rowid in (select head_rowid from CHAINED_ROWS);
SQL> select count(*) from test_temp;

COUNT(*)
----------
105

2、删除行迁移的行
select rowid,employee_id from test;
delete from test where rowid in (select head_rowid from CHAINED_ROWS)
SQL> delete from test where rowid in (select head_rowid from CHAINED_ROWS);

105 rows deleted.

SQL> select count(*) from test;

COUNT(*)
----------
2

3、插入
insert into test select * from test_temp;
SQL> select count(*) from test;

COUNT(*)
----------
107
commit;
truncate table CHAINED_ROWS;
查看有没有行迁移
analyze table test list chained rows into CHAINED_ROWS;
select table_name,count(*) from CHAINED_ROWS group by table_name;

set autotrace traceonly statistics;
select /*+index(test,idx_test_id) */ * from test where employee_id>0;

结果为:
SQL> select /*+index(test,idx_test_id) */ * from test where employee_id>0;

107 rows selected.

Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
116 consistent gets
0 physical reads
0 redo size
437625 bytes sent via SQL*Net to client
601 bytes received via SQL*Net from client
9 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
107 rows processed

结论:对比一下行迁移之前读了288 block 现在只要读了116个 block;

案例2:行连接 说明一行的数据超过8192bytes
truncate table CHAINED_ROWS;
drop table test_temp purge;
drop table test purge;
set autotrace off;
create table test as select * from hr.employees;
create index idx_test_id on test(employee_id);
set autotrace traceonly statistics;
select /*+ index(test,idx_test_id)*/ * from test;
set autotrace off;
alter table test modify last_name varchar2(2000);
alter table test modify first_name varchar2(2000);
alter table test modify email varchar2(2000);
alter table test modify phone_number varchar2(2000);
update test set LAST_NAME=lpad('1',2000,'*'),FIRST_NAME=lpad('1',2000,'*'),EMAIL=lpad('1',2000,'*'),PHONE_NUMBER=lpad('1',2000,'*');
commit;

SQL> desc test;
Name Null? Type
----------------------------------------- -------- ----------------------------
EMPLOYEE_ID NUMBER(6)
FIRST_NAME VARCHAR2(2000)
LAST_NAME NOT NULL VARCHAR2(2000)
EMAIL NOT NULL VARCHAR2(2000)
PHONE_NUMBER VARCHAR2(2000)
HIRE_DATE NOT NULL DATE
JOB_ID NOT NULL VARCHAR2(10)
SALARY NUMBER(8,2)
COMMISSION_PCT NUMBER(2,2)
MANAGER_ID NUMBER(6)
DEPARTMENT_ID NUMBER(4)

set autotrace traceonly statistics;
select /*+ index(test,idx_test_id)*/ * from test;

107 rows selected.

Statistics
----------------------------------------------------------
28 recursive calls
0 db block gets
399 consistent gets
0 physical reads
0 redo size
869120 bytes sent via SQL*Net to client
601 bytes received via SQL*Net from client
9 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
107 rows processed

set autotrace off;
analyze table test list chained rows into CHAINED_ROWS;
select table_name,count(*) from CHAINED_ROWS group by table_name;
SQL> select table_name,count(*) from CHAINED_ROWS group by table_name;

TABLE_NAME COUNT(*)
------------------------------ ----------
TEST 214

那如何消除行连接呢?
SQL> show parameter 16k

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_16k_cache_size big integer 0

alter system set db_16k_cache_size=20m;
select name from v$datafile;
SQL> select name from v$datafile;

NAME
--------------------------------------------------------------------------------
+DATA/orcl/datafile/system.256.943301251
+DATA/orcl/datafile/sysaux.257.943301251
+DATA/orcl/datafile/undotbs1.258.943301251
+DATA/orcl/datafile/users.259.943301251
+DATA/orcl/datafile/example.265.943301433

创建16K的表空间(之前默认1个block是8192bytes字节)
create tablespace tbs_16k blocksize 16K datafile '+DATA/orcl/datafile/tbs.dbf' size 10m;
alter table test move tablespace tbs_16k;

truncate table CHAINED_ROWS;
analyze table test list chained rows into CHAINED_ROWS;
select table_name,count(*) from CHAINED_ROWS group by table_name;

因为刚才对表空间进行了move,因此test的索引生效了,需要重建索引。
alter index idx_test_id rebuild;

set autotrace traceonly statistics;
select /*+ index(test,idx_test_id)*/ * from test;

SQL> select /*+ index(test,idx_test_id)*/ * from test;

107 rows selected.

Statistics
----------------------------------------------------------
36 recursive calls
0 db block gets
177 consistent gets
0 physical reads
0 redo size
867337 bytes sent via SQL*Net to client
601 bytes received via SQL*Net from client
9 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
107 rows processed

结论:读107行数据, 对比之前读了399个block,现在只读了177个block
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据库 存储 管理
相关文章推荐