轉: 關於oracle 是按照寫入順序還是ROWID順序取資料

jidongzheng發表於2011-07-18

答案是: ROWID順序

以下是轉的測試內容:

[@more@]

建立一個1M的表空間:

SQL> SHOW PARAMETER BLOCK_SIZE

NAME TYPE VALUE
------------------------------------ ----------- -----------------------
db_block_size integer 8192

SQL> CREATE TABLESPACE TEST DATAFILE 'E:ORACLEORADATAYTK102TEST01.DBF' SIZE 1M;

表空間已建立。

下面建立一張表佔用資料檔案的大部分空間:

SQL> CREATE TABLE T_TEST (ID NUMBER, NAME VARCHAR2(30)) TABLESPACE TEST
2 STORAGE (INITIAL 896K);

表已建立。

去掉資料檔案的頭資訊,這個資料檔案只有不到128k的可用空間了,下面建立目標表,為了方便,目標表包含了三個CHAR(2000)的欄位,這樣每條記錄都會佔用1BLOCK,加上表頭的三個BLOCK,這張表最大隻能插入5條記錄:

SQL> CREATE TABLE T_TEST1 (ID NUMBER, C1 CHAR(2000), C2 CHAR(2000), C3 CHAR(2000))
2 TABLESPACE TEST STORAGE (INITIAL 64K);

表已建立。

SQL> INSERT INTO T_TEST1 VALUES (1, 'A', 'A', 'A');

已建立 1 行。

SQL> INSERT INTO T_TEST1 VALUES (2, 'A', 'A', 'A');

已建立 1 行。

SQL> INSERT INTO T_TEST1 VALUES (3, 'A', 'A', 'A');

已建立 1 行。

SQL> INSERT INTO T_TEST1 VALUES (4, 'A', 'A', 'A');

已建立 1 行。

SQL> INSERT INTO T_TEST1 VALUES (5, 'A', 'A', 'A');

已建立 1 行。

SQL> INSERT INTO T_TEST1 VALUES (6, 'A', 'A', 'A');
INSERT INTO T_TEST1 VALUES (6, 'A', 'A', 'A')
*
1 行出現錯誤:
ORA-01653:
YANGTK.T_TEST1 無法透過 8 (在表空間 TEST ) 擴充套件

檢查現在的讀取順序:

SQL> SELECT ID, ROWID FROM T_TEST1;

ID ROWID
---------- ------------------
3 AAAPFGAAJAAAAB8AAA
4 AAAPFGAAJAAAAB9AAA
5 AAAPFGAAJAAAAB+AAA
1 AAAPFGAAJAAAAB/AAA
2 AAAPFGAAJAAAACAAAA

可以看到,當前的讀取順序確實不是按照插入順序進行的,而是根據ROWID的順序進行的讀取。

下面刪除剛才建立的T_TEST,插入一條新的記錄,再次檢查讀取順序:

SQL> DROP TABLE T_TEST PURGE;

表已刪除。

SQL> INSERT INTO T_TEST1 VALUES (6, 'A', 'A', 'A');

已建立 1 行。

SQL> SELECT ID, ROWID FROM T_TEST1;

ID ROWID
---------- ------------------
3 AAAPFGAAJAAAAB8AAA
4 AAAPFGAAJAAAAB9AAA
5 AAAPFGAAJAAAAB+AAA
1 AAAPFGAAJAAAAB/AAA
2 AAAPFGAAJAAAACAAAA
6 AAAPFGAAJAAAAAJAAA

已選擇6行。

由於資料檔案前面的BLOCK被釋放,T_TEST1表新擴充套件的EXTENTBLOCK_ID要小於原EXTENTBLOCK_ID,因此ID6的記錄的ROWID明顯比前面5條記錄的ROWID要小,顯然Oracle並不是根據ROWID大小順序來讀取記錄的。不過同一個EXTENT中,Oracle是根據這個順序來讀取的。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/197458/viewspace-1052643/,如需轉載,請註明出處,否則將追究法律責任。

相關文章