1. 程式人生 > >10、管理數據庫存儲(行遷移及行連接)

10、管理數據庫存儲(行遷移及行連接)

管理數據庫存儲(行遷移及行連接)

管理數據庫存儲

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






本文出自 “梁小明的博客” 博客,請務必保留此出處http://7038006.blog.51cto.com/7028006/1930684

10、管理數據庫存儲(行遷移及行連接)