[20121019]8k資料塊到底能放多少行記錄.txt
[20121019]8k資料塊到底能放多少行記錄.txt
前一陣子聚會,被問及一個8k資料塊能夠放多少行記錄,我記得以前piner的書提高過,73X條.
實際上表sys.tab$的spare1欄位儲存的Hakan Factor,即該表資料塊的最大行號,各種資料塊的大小不同,
spare1的預設值也不一樣。
_______________________________
塊大小 最大行數每塊(spare1)
_______________________________
2K 178
4K 364
8k 736
16K 1481
32K 2971
_______________________________
自己做一些簡單探究看看:
SQL> select * from v$version ;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production
CREATE TABLESPACE USERS DATAFILE
'/u01/app/oracle11g/oradata/test/users01.dbf' SIZE 512M AUTOEXTEND ON NEXT 16M MAXSIZE UNLIMITED
LOGGING
ONLINE
PERMANENT
EXTENT MANAGEMENT LOCAL AUTOALLOCATE
BLOCKSIZE 8K
SEGMENT SPACE MANAGEMENT AUTO
FLASHBACK ON;
表空間users使用本地表空間管理的ASSM方式.
1.建立測試例子:
drop table t1 purge ;
create table t1 (a number) pctfree 0;
insert into t1 select null from dual connect by level<=2400;
commit ;
SELECT tab.spare1, obj.object_id, obj.data_object_id, obj.object_name
FROM SYS.tab$ tab, dba_objects obj
WHERE tab.obj# = obj.object_id AND tab.dataobj# = obj.data_object_id AND obj.owner = USER AND obj.object_name = 'T1'
SPARE1 OBJECT_ID DATA_OBJECT_ID OBJECT_NAME
---------- ---------- -------------- ------------
736 115049 115049 T1
--spare1=736
select DBMS_ROWID.ROWID_RELATIVE_FNO(rowid) rfile#,dbms_rowid.ROWID_BLOCK_NUMBER(rowid) block#,count(*) from t1
group by DBMS_ROWID.ROWID_RELATIVE_FNO(rowid),dbms_rowid.ROWID_BLOCK_NUMBER(rowid);
RFILE# BLOCK# COUNT(*)
---------- ---------- ----------
4 550 201
4 548 733
4 549 733
4 547 733
--可以發現最大1個塊能插入733條,與736很接近.
2.那一個塊看看裡面的儲存,我使用bbed看,先執行alter system checkpoint,這樣才能看到準確的結果.
BBED> set dba 4,547
DBA 0x01000223 (16777763 4,547)
BBED> map /v
File: /u01/app/oracle11g/oradata/test/users01.dbf (4)
Block: 547 Dba:0x01000223
------------------------------------------------------------
KTB Data Block (Table/Cluster)
struct kcbh, 20 bytes @0
ub1 type_kcbh @0
ub1 frmt_kcbh @1
ub1 spare1_kcbh @2
ub1 spare2_kcbh @3
ub4 rdba_kcbh @4
ub4 bas_kcbh @8
ub2 wrp_kcbh @12
ub1 seq_kcbh @14
ub1 flg_kcbh @15
ub2 chkval_kcbh @16
ub2 spare3_kcbh @18
struct ktbbh, 72 bytes @20
ub1 ktbbhtyp @20
union ktbbhsid, 4 bytes @24
struct ktbbhcsc, 8 bytes @28
sb2 ktbbhict @36
ub1 ktbbhflg @38
ub1 ktbbhfsl @39
ub4 ktbbhfnx @40
struct ktbbhitl[2], 48 bytes @44
struct kdbh, 14 bytes @100
ub1 kdbhflag @100
sb1 kdbhntab @101
sb2 kdbhnrow @102
sb2 kdbhfrre @104
sb2 kdbhfsbo @106
sb2 kdbhfseo @108
sb2 kdbhavsp @110
sb2 kdbhtosp @112
struct kdbt[1], 4 bytes @114
sb2 kdbtoffs @114
sb2 kdbtnrow @116
sb2 kdbr[733] @118
ub1 freespace[4405] @1584
ub1 rowdata[2199] @5989
ub4 tailchk @8188
--可以發現ub1 rowdata[2199] @5989,2199/733=3,每天記錄佔用3個位元組.
--ub1 freespace[4405] @1584,可以發現自由空間還有很大的剩餘.4405,如果使用dump /v看也一樣.
--sb2 kdbr[733] @118 --> 行目錄7佔用33條.
--所以理論講應該還能儲存更多的行記錄.
3.使用ALTER TABLE MINIMIZE RECORDS_PER_BLOCK看看:
首先確定這個命令修改有最大行記錄確定還是每塊的最大的記錄數.再建立一個測試表T2.
drop table t2 purge ;
create table t2 (a number) pctfree 0;
insert into t2 select null from dual connect by level<=10;
delete from t2;
insert into t2 select null from dual connect by level<=10;
commit ;
select dbms_rowid.rowid_relative_fno(rowid) rfile#,dbms_rowid.ROWID_BLOCK_NUMBER(rowid) block#,dbms_rowid.ROWID_ROW_NUMBER(rowid) row#,t2.* from t2;
SQL> select dbms_rowid.rowid_relative_fno(rowid) rfile#,dbms_rowid.ROWID_BLOCK_NUMBER(rowid) block#,dbms_rowid.ROWID_ROW_NUMBER(rowid) row#,t2.* from t2;
RFILE# BLOCK# ROW# A
---------- ---------- ---------- ----------
4 555 10
4 555 11
4 555 12
4 555 13
4 555 14
4 555 15
4 555 16
4 555 17
4 555 18
4 555 19
10 rows selected.
--行號從10開始,最大19.
alter table t2 minimize records_per_block;
SELECT tab.spare1, obj.object_id, obj.data_object_id, obj.object_name
FROM SYS.tab$ tab, dba_objects obj
WHERE tab.obj# = obj.object_id AND tab.dataobj# = obj.data_object_id AND obj.owner = USER AND obj.object_name = 'T1'
SPARE1 OBJECT_ID DATA_OBJECT_ID OBJECT_NAME
---------- ---------- -------------- ------------
32787 115050 115050 T2
--SPARE1=32787. 32787-32768=19(不是10),所以執行後儲存的是最大行目錄.這樣設定後每塊最多放20條記錄(行記錄從0開始).
4.這樣這個問題就轉化為一塊能容納多少行目錄.
drop table t2 purge ;
create table t2 (a number) pctfree 0;
declare
v_newrowid rowid;
begin
for i in 1..20000 loop
if i=2000 then
insert into t2 values(NULL);
else
insert into t2 values(null) returning rowid into v_newrowid;
delete from t2 where rowid=v_newrowid;
end if;
end loop;
end;
/
--在一個事務裡面,插入1條記錄佔用1個行目錄,在刪除記錄後,由於在一個事務裡面,不會重用原來的行目錄,這樣最終可以確定能容納多少行目錄.
--為了確定表T2佔用的塊,我選擇i=2000時,插入1條,而不刪除記錄.
commit;
select DBMS_ROWID.ROWID_RELATIVE_FNO(rowid) rfile#,dbms_rowid.ROWID_BLOCK_NUMBER(rowid) block#,count(*) from t2
group by DBMS_ROWID.ROWID_RELATIVE_FNO(rowid),dbms_rowid.ROWID_BLOCK_NUMBER(rowid);
RFILE# BLOCK# COUNT(*)
---------- ---------- ----------
4 555 1
alter system checkpoint;
BBED> set dba 4,555
DBA 0x0100022b (16777771 4,555)
BBED> map /v
File: /u01/app/oracle11g/oradata/test/users01.dbf (4)
Block: 555 Dba:0x0100022b
------------------------------------------------------------
KTB Data Block (Table/Cluster)
struct kcbh, 20 bytes @0
ub1 type_kcbh @0
ub1 frmt_kcbh @1
ub1 spare1_kcbh @2
ub1 spare2_kcbh @3
ub4 rdba_kcbh @4
ub4 bas_kcbh @8
ub2 wrp_kcbh @12
ub1 seq_kcbh @14
ub1 flg_kcbh @15
ub2 chkval_kcbh @16
ub2 spare3_kcbh @18
struct ktbbh, 72 bytes @20
ub1 ktbbhtyp @20
union ktbbhsid, 4 bytes @24
struct ktbbhcsc, 8 bytes @28
sb2 ktbbhict @36
ub1 ktbbhflg @38
ub1 ktbbhfsl @39
ub4 ktbbhfnx @40
struct ktbbhitl[2], 48 bytes @44
struct kdbh, 14 bytes @100
ub1 kdbhflag @100
sb1 kdbhntab @101
sb2 kdbhnrow @102
sb2 kdbhfrre @104
sb2 kdbhfsbo @106
sb2 kdbhfseo @108
sb2 kdbhavsp @110
sb2 kdbhtosp @112
struct kdbt[1], 4 bytes @114
sb2 kdbtoffs @114
sb2 kdbtnrow @116
sb2 kdbr[2014] @118
ub1 freespace[0] @4146
ub1 rowdata[4042] @4146
ub4 tailchk @8188
--sb2 kdbr[2014] @118 ,說明至少可以儲存2014行目錄.(補充說明:我的測試最大2015)
alter table t2 minimize records_per_block;
SELECT tab.spare1, obj.object_id, obj.data_object_id, obj.object_name
FROM SYS.tab$ tab, dba_objects obj
WHERE tab.obj# = obj.object_id AND tab.dataobj# = obj.data_object_id AND obj.owner = USER AND obj.object_name = 'T2'
SPARE1 OBJECT_ID DATA_OBJECT_ID OBJECT_NAME
---------- ---------- -------------- -----------
34767 115130 115130 T2
--spare1=34767,34767-32768=1999,相當於可以每塊可以儲存2000條記錄.實際情況如何呢?
SQL> delete from t2;
1 row deleted.
SQL> commit ;
Commit complete.
SQL> insert into t2 select null from dual connect by level<=2400;
2400 rows created.
SQL> commit;
Commit complete.
select DBMS_ROWID.ROWID_RELATIVE_FNO(rowid) rfile#,dbms_rowid.ROWID_BLOCK_NUMBER(rowid) block#,count(*) from t2
group by DBMS_ROWID.ROWID_RELATIVE_FNO(rowid),dbms_rowid.ROWID_BLOCK_NUMBER(rowid);
RFILE# BLOCK# COUNT(*)
---------- ---------- ----------
4 555 451
4 568 733
4 573 483
4 575 733
--可以發現做多也就是733條記錄.不能超過這個限制.
5.點陣圖索引的問題,由於每塊(8K資料塊)不能超出736的限制.如果行目錄大於736,建立點陣圖索引會出現什麼情況呢?
還是那上面的例子:
drop table t2 purge ;
create table t2 (a number) pctfree 0;
declare
v_newrowid rowid;
begin
for i in 1..20000 loop
if i=2000 then
insert into t2 values(NULL);
else
insert into t2 values(null) returning rowid into v_newrowid;
delete from t2 where rowid=v_newrowid;
end if;
end loop;
end;
/
SQL> create bitmap index i_t2_a on t2(a);
create bitmap index i_t2_a on t2(a)
*
ERROR at line 1:
ORA-28604: table too fragmented to build bitmap index (16777771,1999,744)
$ oerr ora 28604
28604, 00000, "table too fragmented to build bitmap index (%s,%s,%s)"
// *Cause: The table has one or more blocks that exceed the maximum number
// of rows expected when creating a bitmap index. This is probably
// due to deleted rows. The values in the message are:
// (data block address, slot number found, maximum slot allowed)
// *Action: Defragment the table or block(s). Use the values in the message
// to determine the FIRST block affected. (There may be others).
--這裡744表示maximum slot allowed.
select dbms_utility.data_block_address_file(16777771) rfile#,dbms_utility.data_block_address_block(16777771) block# from dual;
RFILE# BLOCK#
---------- ----------
4 555
--執行如下可以解決.
SQL> alter table t2 minimize records_per_block;
Table altered.
SQL> create bitmap index i_t2_a on t2(a);
Index created.
--當然這種極端的情況,在實際上可能很難遇到.或者根本不可能遇到.
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-746749/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- INNODB 到底能存放多少資料?
- 資料行業從業者到底能掙多少錢?行業
- mysql一張表到底能存多少資料?MySql
- MySQL 資料庫 到底能支撐多少表?MySql資料庫
- 一天伺服器到底能放多少個網站呢?伺服器網站
- [20230223]8k資料塊建立最大檔案是多少(ORA-03206).txt
- 大資料的魔力你到底知道多少大資料
- 10g 資料檔案頭到底有多少資料塊,還是說固定有多大?
- [20170412]bbed隱藏資料記錄.txt
- 透過DNS TXT記錄執行powershellDNS
- ACCESS 統計報表有多少行記錄
- [20140624]bbed修改資料記錄.txt
- 記錄刪除後,資料塊空間不釋放,請大家幫忙看看分析一下
- 面試題:InnoDB中一棵B+樹能存多少行資料?面試題
- 資料填充檔案最大一次能執行多少條sqlSQL
- [20121214]資料庫錯誤記錄.txt資料庫
- [20160526]bbed修改資料記錄(不等長).txt
- [20200814]8K資料庫最大行號.txt資料庫
- 資料分析告訴你,炒股能賠多少錢?
- 熱門APP能賺多少錢?–資料資訊圖APP
- 查詢某條記錄存在哪個資料塊中
- [20170419]bbed探究資料塊.txt
- [20140624]bbed修改資料記錄(不等長).txt
- 資料標註行業知多少行業
- 改變資料頁大小能帶來多少收益?
- 多執行緒,到底該設定多少個執行緒?執行緒
- [20211009]8K資料庫最大行號補充.txt資料庫
- 獲取當前修改的行記錄資料
- Java 17到底快了多少?Java
- oracle資料塊中資料儲存(摘錄)Oracle
- 物件有多少個資料塊緩衝在Data buffer中物件
- [20210128]拼接資料塊.txt
- [20150929]檢查資料塊.txt
- PHP陣列到底佔用多少記憶體空間PHP陣列記憶體
- 查欄位指定資料後一行記錄
- [20150720]為什麼8K資料塊Hakan Factor=736
- 資料庫資料跟蹤記錄資料庫
- oracle實驗記錄 (恢復,備份-含壞塊資料檔案)Oracle