表熱塊的處理手段分析
前言:
熱塊在我們的日常資料庫中,是最常見的問題之一,怎樣來解決問題,沒有一個統一的方法,只有透過實驗,結合實際情況來減少熱塊的發生,下面來分析一下幾種能夠解決熱塊的手段之間的不同。
熱塊是由於同時訪問某些塊太過頻繁而出現的效能問題。從這一點來說,我們可以讓塊所包含的資料少一點,那麼訪問資料的使用者就會分散到不同的塊上。還有就是我們可以透過hash演算法來將連續插入的資料分散儲存在不同的塊中,這樣使用者訪問資料也會分散到不同的塊上。
//建立普通表
SQL> create table test111
2 (id number,
3 name varchar2(20));
//指定pctfree的表
create table test222
(id number,
name varchar2(20))
pctfree 60
;
//建立hash表
CREATE TABLE test333
(id number,
name varchar2(20))
PARTITION BY HASH (id)(
PARTITION pid1,
PARTITION pid2,
PARTITION pid3,
PARTITION pid4,
PARTITION pid5,
PARTITION pid6,
PARTITION pid7,
PARTITION pid8,
PARTITION pid9,
PARTITION pid10
);
//建立普通表,指定minimize records_per_block屬性
create table test444
(id number,
name varchar2(20));
alter table test444 minimize records_per_block;
Table created.
SQL> 2 3 4 5
Table created.
SQL> 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Table created.
SQL> 2 3
Table created.
SQL> alter table test444 minimize records_per_block;
alter table test444 minimize records_per_block
*
ERROR at line 1:
ORA-28603: statement not permitted on empty tables
SQL> insert into test444 values (111,'111');
1 row created.
SQL> commit;
Commit complete.
SQL> alter table test444 minimize records_per_block;
Table altered.
SQL> truncate table test444;
Table truncated.
//建立模擬資料
SQL> create or replace procedure p_test
2 as
3 begin
4 for i in 1..100000 loop
5 insert into test111 values (i,to_char(i));
6 insert into test222 values (i,to_char(i));
7 insert into test333 values (i,to_char(i));
8 insert into test444 values (i,to_char(i));
9 commit;
10 end loop;
11 end p_test;
12 /
Procedure created.
SQL> exec p_test;
PL/SQL procedure successfully completed.
SQL> commit;
Commit complete.
//分析1:4種不同型別的表,佔用的塊數
SQL> select count(distinct dbms_rowid.ROWID_BLOCK_NUMBER(rowid)) from test111 ;
COUNT(DISTINCTDBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID))
---------------------------------------------------
218
SQL> select count(distinct dbms_rowid.ROWID_BLOCK_NUMBER(rowid)) from test222;
COUNT(DISTINCTDBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID))
---------------------------------------------------
492
SQL> select count(distinct dbms_rowid.ROWID_BLOCK_NUMBER(rowid)) from test333;
COUNT(DISTINCTDBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID))
---------------------------------------------------
221
SQL> select count(distinct dbms_rowid.ROWID_BLOCK_NUMBER(rowid)) from test444;
COUNT(DISTINCTDBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID))
---------------------------------------------------
50000
//4種不同型別的表,塊包含的行數分析
SQL> select tt.block_rows,count(1) from (
select dbms_rowid.ROWID_BLOCK_NUMBER(rowid) blockid,count(1) block_rows from test111 group by dbms_rowid.ROWID_BLOCK_NUMBER(rowid))
tt group by tt.block_rows; 2 3
BLOCK_ROWS COUNT(1)
---------- ----------
574 1
155 1
461 1
549 1
519 17
454 197
6 rows selected.
SQL> select tt.block_rows,count(1) from (
select dbms_rowid.ROWID_BLOCK_NUMBER(rowid) blockid,count(1) block_rows from test222 group by dbms_rowid.ROWID_BLOCK_NUMBER(rowid))
tt group by tt.block_rows;
2 3
BLOCK_ROWS COUNT(1)
---------- ----------
247 3
209 1
229 39
262 1
201 447
10 1
6 rows selected.
SQL>
SQL> select tt.block_rows,count(1) from (
select dbms_rowid.ROWID_BLOCK_NUMBER(rowid) blockid,count(1) block_rows from test333 group by dbms_rowid.ROWID_BLOCK_NUMBER(rowid))
tt group by tt.block_rows;
2 3
BLOCK_ROWS COUNT(1)
---------- ----------
399 1
91 1
485 1
472 1
470 1
529 2
155 1
481 1
523 1
230 1
331 1
BLOCK_ROWS COUNT(1)
---------- ----------
532 1
467 2
464 1
528 1
519 6
483 1
525 2
277 1
473 1
381 1
454 185
BLOCK_ROWS COUNT(1)
---------- ----------
530 2
203 1
480 1
524 1
406 2
27 rows selected.
SQL> select tt.block_rows,count(1) from (
select dbms_rowid.ROWID_BLOCK_NUMBER(rowid) blockid,count(1) block_rows from test444 group by dbms_rowid.ROWID_BLOCK_NUMBER(rowid))
tt group by tt.block_rows;
2 3
BLOCK_ROWS COUNT(1)
---------- ----------
2 50000
SQL>
分析:從上面的分析來看,普通表,每個塊都包含了400~500行記錄。使用了pctfree的塊大部分只包含了200~250行記錄。hash表的大部分塊也包含了400~500行記錄。指定指定minimize records_per_block屬性的表最規矩,沒個塊只包含了2條記錄。
從以上的資料統計來看,指定minimize records_per_block屬性的方式不可取,這樣會導致讀塊的個數增加數倍,對io壓力太大。使用pctfree達到了我們的目的,減少塊所包含的資料量。hash表跟普通表大部分塊所包含的資料量都是相近的。但是我們要注意一點,hash表所包含的資料並不是有序的,從這一點來說,對熱塊的解決也是有幫助的。
從以上的分析來看,pctfree可以減少塊包含的行數,hash表可以打亂連續插入資料的分佈情況,這2種手段都可以緩解熱塊情況。我們何不把這2種手段結合起來用呢?
SQL>
SQL>
SQL> create table test555
(id number,
name varchar2(20))
pctfree 60
PARTITION BY HASH (id)(
PARTITION pid1,
PARTITION pid2,
PARTITION pid3,
PARTITION pid4,
PARTITION pid5,
PARTITION pid6,
PARTITION pid7,
PARTITION pid8,
PARTITION pid9,
PARTITION pid10
); 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Table created.
SQL>
create or replace procedure p_test
as
begin
for i in 1..100000 loop
insert into test555 values (i,to_char(i));
commit;
end loop;
end p_test;
/
SQL> 2 3 4 5 6 7 8 9
Procedure created.
SQL> exec p_test
PL/SQL procedure successfully completed.
SQL> select count(distinct dbms_rowid.ROWID_BLOCK_NUMBER(rowid) ) from test555;
COUNT(DISTINCTDBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID))
---------------------------------------------------
496
SQL> select tt.block_rows,count(1) from (
select dbms_rowid.ROWID_BLOCK_NUMBER(rowid) blockid,count(1) block_rows from test555 group by dbms_rowid.ROWID_BLOCK_NUMBER(rowid))
tt group by tt.block_rows; 2 3
BLOCK_ROWS COUNT(1)
---------- ----------
153 1
213 1
235 1
218 2
229 27
205 1
224 1
201 388
240 2
161 1
230 1
BLOCK_ROWS COUNT(1)
---------- ----------
135 1
242 1
239 2
206 1
75 1
8 1
200 50
214 1
107 1
241 1
99 1
BLOCK_ROWS COUNT(1)
---------- ----------
221 2
216 1
236 1
158 2
9 1
234 2
28 rows selected.
用這種方式,既保證了每個塊包含的行數減少,也保證了連續的資料分佈在不同的塊中儲存。筆者覺得用這種方式來實現表的建立能夠最大程度的把對資料的訪問分散到表所包含的所有塊上,也減少了塊包含的資料。這需要實踐來檢驗。至於pctfree和hash分割槽的個數,也沒有什麼固定值,需要dba透過經驗和系統的情況來調整,當然最有效的辦法就是測試了。透過測試來找到一個最佳值。
RAC全域性熱塊的處理手段可參考文章:http://blog.csdn.net/csucxcc/article/details/5896309
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23135684/viewspace-673241/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- bad block表上壞塊的處理BloC
- 熱點塊處理是首先應該處理物件呢?還是優化sql。物件優化SQL
- 成品app直播原始碼搭建,常用資料處理手段程式碼分析APP原始碼
- 高併發處理思路與手段(一):擴容
- Oracle壞塊處理Oracle
- rootvg壞塊處理
- ORACLE 壞塊處理Oracle
- 處理塊損壞
- 關於專案中遇到的NullPointerException異常時處理手段NullException
- BAD Block 壞塊的處理BloC
- MySQL的表碎片處理MySql
- 深度分析ORACLE熱點塊問題Oracle
- SELECT大表的處理
- 深度分析資料庫的熱點塊問題資料庫
- ORACLE資料庫壞塊的處理 (處理無物件壞快的方法)Oracle資料庫物件
- DBA實踐---壞塊處理
- 資料庫壞塊處理資料庫
- Oracle壞塊處理相關Oracle
- Oracle壞塊問題處理Oracle
- oracle corrupt block壞塊處理OracleBloC
- Nginx支援.htaccess的分析處理Nginx
- 深度分析ORACLE熱點塊問題(轉)Oracle
- 處理方塊之間的連線線
- 對oracle中出現的壞塊的處理方法Oracle
- 深度分析資料庫的熱點塊問題(轉)資料庫
- 深度分析資料庫的熱點塊問題 (zt)資料庫
- 處理表鎖定的情況
- Oracle冷備份和熱備份的處理Oracle
- CC Arithmetic Progressions (FFT + 分塊處理)FFT
- 第7章 處理塊損壞
- 定位熱鏈和熱塊的方法
- ORACLE資料庫壞塊的處理 (一次壞快處理過程)Oracle資料庫
- PHP表單處理指南PHP
- 一次壞塊的處理過程(一)
- 一次壞塊的處理過程(二)
- 資料庫壞塊Corrupt block的處理方法資料庫BloC
- EBS 迴圈處理塊記錄的程式碼
- 一次壞塊的處理過程 [轉]