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、管理數據庫存儲(行遷移及行連接)