您好,登錄后才能下訂單哦!
對于優(yōu)化器而言,它在解析目標SQL,得到執(zhí)行計劃時至關重要的一點是決定訪問數(shù)據(jù)的方法,即優(yōu)化器要決定采用什么樣的方式和方法去訪問目標SQL所需要訪問的存儲在oracle數(shù)據(jù)庫中的數(shù)據(jù)。
目標SQL所需要訪問的數(shù)據(jù)一般存儲在表里,而oracle訪問表中數(shù)據(jù)的方法有兩種:一種直接訪問表,另一種是先訪問索引,在回表(當然,如果目標sql所要訪問的數(shù)據(jù)只通過訪問相關的索引就可以得到,那么此時就不需要回表了)
oracle數(shù)據(jù)庫中直接方位表中數(shù)據(jù)的方法有兩種:一是全表掃描,而是rowid掃描
1. 全表掃描
全掃描時指oracle在訪問目標表里數(shù)據(jù)時,會從該表所占用的第一個區(qū)(EXTENT)的第一個塊(BLOCK)開始掃描,一直掃描到該表的高水位線(HWM),這段范圍內(nèi)所有的數(shù)據(jù)塊oracle都必須讀到。當然oracle會對這期間讀到的所有數(shù)據(jù)施加目標SQL的where條件中指定的條件,最后只返回那些滿足過濾條件的數(shù)據(jù)。
不是全表掃描不好,事實上oracle在做全表掃描操作時會使用多塊讀,這在目標表的數(shù)據(jù)量不大時執(zhí)行效率是非常高的,但全表掃描最大問題就在于走全表掃描的目標sql的執(zhí)行時間不穩(wěn)定,不可控,這個執(zhí)行時間一定會隨著目標表數(shù)據(jù)量的遞增而遞增。因為隨著目標表數(shù)據(jù)量的遞增,它的高水位線會一直不斷上漲,所以全表掃描該表時所需要讀取的數(shù)據(jù)塊的數(shù)量也不斷增加,這意味著全表掃描該表時所需要耗費的I/O資源隨之不斷增加,當然完成對該表的全掃描所需要耗費的時間也會隨之增加。另外,對于CBO而言,所要耗費I/O資源不斷增加意味著全表掃描的成本值也會隨著目標表數(shù)據(jù)量的遞增而遞增。
在oracle中,如果對目標表不停地插入數(shù)據(jù),當分配給該表的現(xiàn)有空間不足時高水位線就會向上移動,但如果你用delete語句從該表中刪除數(shù)據(jù),則高水位線并不會隨之往下移動。高水位線的這種特性帶來的負作用是,即使使用delete語句刪除所有數(shù)據(jù),高水位線還是再原來的位置,這意味這個全表掃描該表時還是需要掃描該表高水位線下的所有數(shù)據(jù)塊,所以此時對該表的全表掃描操作所耗費的時間與之前相比不會有明細的改善。
2.ROWID掃描
ROWID掃描是指oracle在訪問目標表里的數(shù)據(jù)時,直接通過數(shù)據(jù)所在的rowid去定位并訪問這些數(shù)據(jù)。rowid表示的是oracle的數(shù)據(jù)行記錄所在物理存儲地址,也就是說rowid實際上是和oracle中數(shù)據(jù)塊里的行記錄一一對應的。
既然rowid代表的就是表的數(shù)據(jù)行所在的物理存儲地址,那么當oracle知道待訪問的數(shù)據(jù)行所在rowid后,自然就可以根據(jù)rowid去直接訪問對應表的相關數(shù)據(jù)行,這就是rowid的定義。
從嚴格意思來說,oracle中rowid掃描有兩層含義:一種是根據(jù)用戶在sql語句中輸入rowid的值直接訪問對應的數(shù)據(jù)行記錄;另一種是先去訪問相關的索引,然后根據(jù)訪問索引后得到的rowid再回表去訪問對應的行記錄。
對oralce中堆表而言,我們可以通過內(nèi)置的rowid偽劣得到對應行記錄所在的rowid的值(注意,這個rowid只是一個偽劣,在實際的表塊中并不存在該列)然后我們可以通過dbms_rowid包中的相關方法(dbms_rowid.rowid_relative_fno,dbms_rowid.rowid_block_number和dbms_rowid.rowid_row_number)將上述偽列的值翻譯成對應數(shù)據(jù)行的實際物理存儲地址。
SQL> select empno,ename,rowid,dbms_rowid.rowid_relative_fno(rowid)||'_'||dbms_rowid.rowid_block_number(rowid)||'_'||dbms_rowid.rowid_row_number(rowid) location from emp;
EMPNO ENAME ROWID LOCATION
---------- ---------- ------------------ --------------------------------------------------
7369 SMITH AAAVREAAEAAAACXAAA 4_151_0
14 rows selected.
從上述顯示內(nèi)容可以看出,empno為7369的行記錄所對應的rowid偽列的值為“AAAVREAAEAAAACXAAA ”,使用dbms_rowid包對該列翻譯后的值為4_151_0,這表是empno為7369的行記錄實際的物理存儲地址位于4號文件第151個數(shù)據(jù)塊的第0行記錄(數(shù)據(jù)塊里數(shù)據(jù)行記錄的記錄號從0開始算起)
上述rowid偽列的值是可以直接在sql語句中where條件中使用的,這就是oralce中rowid掃描的兩層含義中第一種,根據(jù)用戶在sql語句中輸入的rowid的值直接去訪問數(shù)據(jù)行記錄。
SQL> select empno,ename from emp where rowid='AAAVREAAEAAAACXAAL';
EMPNO ENAME
---------- ----------
7900 JAMES
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。