打開oracle sqldeveloper,連接到HR模式下的數據庫,在SQL工作表中,執行如下語句:

CREATE TABLE WANG(

Name  varchar26),

ID     number        );

然後向表中插入如下語句:

INSERT INTO WANG VALUES(‘WANG’,1)

INSERT INTO WANG VALUES(‘CHENG’,2);

INSERT INTO WANG VALUES(‘ZHOU’,3);

INSERT INTO WANG VALUES(‘HE’,4);

Commit;

Sqldeveloper查詢入下圖所示:


 

下面將分別介紹三種數據讀取方式:

1.通過全表掃描

在使用全表掃描的時候,利用多塊讀,oracle讀取表中的所有行,可以提高全表掃描的速度,可以大大的減少I/O的次數,是一種很好的讀取方法,通常採用全表掃描,但是讀取較大的表時,不建議採取全表掃描的方法。

那我們查看下采取全表掃描先:

sql工作表中執行

Explain  plan  for  select  *  from  wang;

Select  *  from  table(dbms_xplan.display);

如下圖:




發現第七行TABLE  ACCESS  FULL了吧。

2.通過ROWID

我們在對錶對象採取數據插入時,會隱含創建ROWID,是64進制數,它是數據行所存儲的數據塊地址,所以我們可以通過查找ROWID可以快速查找到我們想要查找的數據。ROWID中指出了對象編號,數據文件編號,塊號,行號。那我們來看下到底什麼是ROWID

SQL工作表中執行

Select  name,id ,rowid  from  wang;

如下圖所示:




ROWID總共有十八位,以第一行的ROWID爲例:

AAASVp  AAE  AAAAKP  AAA

它是64進制數,我們來分析下rowid中各個字符代表什麼:

A~Z 代表0~25

a~z  代表26~51

0~9  代表52~61

+    代表 62

/     代表 63

細心的讀者可以發現我把上面的十八位分成了四小組:

第一組(前六位):是代表對象的編號

第二組(三位):文件編號

第三組(六位):塊編號

第四組(三位):行號

既然是十六進制數,那我們轉換成十進制數看看先(以對象編號爲例):

AAASVp

0+0+0+18*64*64+ 21*64+ 41=75113

我們可以在視圖中查找對象編號來驗證上面我們通過ROWID計算得到的對象編號正確性。打開sqlplus窗口,執行下面語句:

Select object_name,data_object_id from dba_objects where object_name=’wang’;

結果如下圖:




通過上面的實驗,你是否理解ROWID的含義了呢,同理,文件編號,塊編號,行編號可以通過此方法得到驗證,讀者自己可以嘗試去實驗。

我們可以比較ROWID和全表掃描哪個更快:

sqldeveloperSQL工作表中執行:

Explain  plan  for  select  *  from  wang  where  rowid=’AAASVp AAE AAAAKP AAA’;

Select  *  from  table(dbms_xplan.display);

結果如下圖:




通過比較,通過ROWID查找數據是最快的。

3.通過索引

我們可以通過索引找到數據行的 ROWID,然後通過ROWID直接到表中查找數據,這種方式爲索引查找或者稱爲索引掃描。因爲一個ROWID對應一個數據行,所以這種方式是採用的單塊讀取。索引中不僅存儲索引值,還存儲相應的ROWID。索引查找分爲兩步,掃描索引找到相應的ROWID,人後找到對應的ROWID然後從表中讀取相應的數據。每次都是單塊的I/O去讀,由於索引比較小,而且經常使用,一般會被緩存到內存中,並且第一步通常是邏輯讀(數據可以從內存中得到),由於表數據較大,第二步通常爲物理讀(邏輯讀的速度是大於物理讀取,物理讀性能比較低)。我們創建了索引,但是是否使用是ORACLE根據CBO優化器計算的結果選擇,普通用戶是無法干預的。

我們來做下實驗,訪問路徑走主鍵索引的查詢(此時已在sqldeveloper中把WANG.ID設爲主鍵)。

Sqldeveloper中的SQL工作表中執行以下語句:

Explain plan for select * from wang where id=’1’;

Select * from table(dbms_xplan.display);

結果如下圖:

由下圖我們可以看出訪問路徑走的是主鍵索引,所以你看到的是INDEX UNIQUE SCAN,首先是索引掃描,然後是根據索引查找到ROWID進行表的訪問。

 

你也許會問,我們不是沒有創建索引嗎,怎麼會通過索引來查找呢,因爲我們在指定主鍵時,Oracle會自動創建主鍵索引,是唯一索引。我們可以創建一般索引,唯一索引,位圖索引等。

完整語法:

CREATE (UNIQUE|BITMAP) INDEX [用戶名.]索引名 ON [用戶名.]表名 (列名 [ ASC | DESC], [列名 [ ASC | DESC]]...)

[ TABLESPACE 表空間名 ]

[ PCTFREE 正整型數 ]

[ INITRANS 正整型數 ]

[ MAXTRANS 正整型數 ]

[ 存儲子句 ]

[ LOGGING | NOLOGGING ]

[ NOSORT ]

ORACLE自動創建的主鍵索引是什麼樣的呢?那我們來看看先:

Select * from user_indexes where table_name=’WANG’;



我們知道原來這個索引名字叫WANG_PK,知道爲什麼叫主鍵索引了吧,索引涉及到優化,不是我們創建了索引,就會使用索引,要根據優化器選擇。事物都有兩面性,它可以幫助我們快速找到想要的數據,但是在有些情況下會帶來性能開銷,不要認爲使用索引就是好事。索引掃描有四種方式:唯一掃描,範圍掃描,全掃描,快速掃描,這裏不一一敘述。有時候我們創建了索引,我們也可以限制索引,如我們使用了函數,但是沒有創建基於該函數的索引。鑑於本人水平有限,索引涉及的內容遠遠超過這些,對有興趣的讀者可以更深入的瞭解索引。Oracle是一座巨大礦山,值得學數據庫的你去探索,oracle中它真的很棒,從它的體系結構到很小的一部分可以說都做的很好,給我們帶來很大的方便,在這個多用戶的時代,它的優勢更加的顯著,市場佔有率可以說明這一點。