一.相關概念
1·rowid,僞列:就是系統自己給加上的,每個表都有一個僞列,並不是物理存在。它不能被修改,刪除,和添加,rowid在該行的生命週期是唯一的,如果向數據庫插入一列,只會引起行的變化,但是rowid並不會變。
2·recursive sql概念:當用戶執行一些SQL語句時,會自動執行一些額外的語句,我們把這些額外的SQL語句稱爲“recursive calls” 或者是“recursive sql statement”,當在執行一個DDL語句時,Oracle總會隱含的發出一些Recursiv sql語句,用於修改數據字典,如果數據字典沒有在共享內存中,則就執行“resursive calls”,它會把數據字典從物理讀取到共享內存。當然DML和select語句都可能引起recursive SQL。
3·row source 行源:在查詢中,由上一操作返回的符合條件的數據集,它可能是整個表,也可能是部分,當然也可以對2個表進行連接操作(join)最後得到的數據集
4·predicate:一個查詢中的where限制條件
5·driving table 驅動表:該表又成爲外層表,這個感念用於內嵌和HASH連接中,如果返回數據較大,會有負面影響, 返回行數據較小的適合做驅動表
6·probed table 被探查表:該表又稱爲內層表,我們在外層表中取得一條數據,在該表中尋找符合連接的條件的行。
7·組合索引(concatenated index)由多個列組成的索引,在組合索引中有一個重要的概念,就是引導索引,
create index idx_tab on tab(col1,col2,col3),
indx_tab則稱爲組合索引,
col1則稱爲引導列
在查詢條件where後,必須使用引導索引,纔會使用該組合索引
8.可選擇性(selectivity)比較一下列中唯一鍵的數量和表中的行數,就可以判斷該列的可選擇性。 如果該列的“唯一鍵的數量/表中的行數”的比值越接近1,則該列的可選擇性越高,該列就越適合創建索引,同樣索引的可選擇性也越高。在可選擇性高的列上進 行查詢時,返回的數據就較少,比較適合使用索引查詢。
二.Oracle訪問數據的存取方法
1.全表掃描(Full tabel scans,FTS)
爲了實現全表掃描,Oracle讀取數據庫中的每一行,並檢查每一行是否滿足語句的where限制條件一個多塊讀操作,可以使io能讀取多塊數據塊。減少了IO次數,提高了系統的吞吐量。在多塊讀的方法的使用下,可以高效的實現數據庫全表掃描,而且,中有在全表掃描的情況下,在可以使用多塊讀的方法。在這個種訪問模式下,數據塊只讀一次。
【注意】
使用FTS的前提是,在較大的表中,不建議使用FTS,除非取出的數據較多,超過總量的5%-10%,或者使用並行查詢時
2.通過rowid的表存取
行的ROWID指向了該行的數據文件,數據塊,以及在數據塊中的位置,使用rowid能快速的定位到要取得數據的行上,在Oracle中,這是取得單行最快的方式。
【注意】
該存取方法,不會用到多塊讀操作,一次IO只能讀取一個數據塊。
3.索引掃描(index scan 和 index lookup)
索引掃描時通過index查找到對應行的rowid,然後通過rowid從數據庫中得到具體的數據。該方法分爲兩個步驟,
(1)掃描索引得到得到rowid
說明:索引中不止儲存着索引值,還存放的行的rowid
(2)通過rowid得到表中的數據
【注意】
1.由於索引經常使用,因此絕大多數都Cache到內存當中,所以第一步通常是邏輯IO,即數據可以從內存中取得
2.但是對第二步來說,如果數據比較大,就不可能存放在內存,因此是個物理操作,是極其耗時間的,因此,從大表中
進行索引掃描,如果數量大於總數的5%-10%,則效力會下降很多
3.如果索引的數據都能在內存中能找到,就可以避免第二步操作,避免了不必要的IO。效力會很高。
4.如果SQL語句會對索引排序,因爲索引已經預先排好了序,索引在執行計劃中不需要在對索引排序。根據索引的類型與where限制條件的不同,有4種數據類型的索引
1.唯一索引(index unique scan)
通過唯一索引查找一個數值,通常是rowid,如果表中存在unique,或者是primary key的話,Oracle通常實現唯一索引;
2.索引範圍掃描(index range scan)
如果要取得多行數據,通常在唯一索引上加上範圍操作,例如(>,<)
*使用index rang scan的三種情況
(a)在唯一索引上有where條件篩選
(b)在組合索引上,使用部分列進行查詢,導致查詢出多行
(c)對非唯一 索引列進行的任何查詢
3.索引全掃描(index full scan)
與全表掃描想對應的就是全索引掃描,它必要保證要取得的數據都從索引中直接得到
例:
Index BE_IX is a concatenated index on big_emp (empno, ename)
SQL> explain plan for select empno, ename from big_emp order by empno,ename;
4.索引快速掃描(index fash full scan)
索引快速掃描和index full scan相似,不會對查詢出的數據進行排序。
三.表之間的連接
根據row source連接的條件不同,可以分爲等值連接(where a.col3=b.col4)非等值連接(where a.col3>b.col4)外連接 (where a.col3=b.col4(+))
1.典型的連接類型
(a)排序--合併連接(sort merge join,SMJ)
(b)嵌套循環(nested loops,NL)
(c)哈希連接(hash join,)
A.排序--合併連接
1)首先生成row source1需要的數據,讓後對連接關聯的列進行排序。
2)然後生成row source2需要的數據,然後對這些數據按照與row socurce1相對應的操作關聯列進行排序。
3)將兩邊排好序的數據進行合併操作,將2個row source按照連接條件連接起來。
[注意]
·.如果row source已經在關聯上列上被排序,那個連接操作就不會執行sort操作,將大大的提高效率,因爲排序時極其 消耗資源的,預先被排序的row source包括索引,或者已經排好序的列。
·.排序是非常耗時的操作,尤其是大表,基於這個原因,SMJ通常不是一個好的解決辦法,如果排序的工作早已做好那將極大的提高效率
·.對於非等值連接,這種連接方式的效率是比較高的。
B.嵌套循環。
在連接有驅動表的概念,實際上連接過程就是2層嵌套循環,外層表越小越好。
[執行原理]
從內部表來看,需要得到外層表的每一行,去匹配內部表的所有行,因此保持外部表儘可能小,和高效率訪問內部表,是連接性能的關鍵。
[優點]
nested loops可以返回已經連接的行,而不必等待所有的行連接完,因此能快速響應,特別適合用在需要快速響應的語句中。
C.hash join
較小的row source用來構建hash table和bitmap,而第二個用來被hansed,並與第一個生成的hash table進行匹配。
bitmap用來作爲一種較快查詢的方法,用來檢查hash table是否有匹配的行,特別在表大的情況下,不能容納在內存中,這個連接方法非常有效。這個鏈接,也有驅動表的概念,有來構造hash table,bitmap的表叫驅動表,如果被 構建的hash table,bitmap都能容納在內存中,這個效率非常高。
【注意】
1) 要使哈希連接有效,需要設置HASH_JOIN_ENABLED=TRUE,缺省情況下該參數爲TRUE,另外,不要忘了還要設置 hash_area_size參數,以使哈希連接高效運行,因爲哈希連接會在該參數指定大小的內存中運行,過小的參數會使哈希連接的性能比其他連接方式還要低。
2)只能用於等值連接。
3)在2個較大的row source之間連接時會取得相對較好的效率,在一個row source較小時則能取得更好的效率。
解釋結果:
1.AND-EQUAL 該步驟具有兩個或更多個子步驟,每一個子步驟返回一系列的ROWID.AND-EQUAL操作選擇的是索引子操作返回的rowid
2.BITMAP
conversoin to rowids --將位圖從位圖索引轉換成可以用於提取實際資料的一系列的ROWID
conversoin from rowids --將一系列的ROWID轉換成位圖表示
conversoin count --對位圖的行數進行統計
index single scan --爲單個索引提取位圖
index range scan --返回的位圖是一定範圍的關鍵值
index full scan --掃描整個位圖索引
MERGE --合併兩個位圖,並作爲一個位圖返回結果
Minus --該操作是merge的相反操作,而且可以具有兩個或3個子操作並返回位圖
第一個子操作返回的位圖用作起點,第一個位圖減去第二個位圖中提供所 有行。如果第二個位圖爲空,那麼所有的null列也將被減去。
or --將兩個位圖作爲輸入
3.connect by --分層提取行,因爲查詢採用了CONNECT BY C從句
4.concatenaction --合併多個行集爲一行。
5.count --計算從表中選擇的行數
stopkey --計算的行數被查詢語句中的where 中的 rownum所限制
6.filter --將一系列的行數作爲輸入,並過濾到where從句查詢而得到的結果
7.first row --提取查詢結果集的第一行
8.for udpate -- 爲提取的行加鎖。
9.hash join --使用散列連接法連接兩張表
10.index
unique --從索引中查找唯一值
range scan --從一定範圍中查找,是按照升序的方式
range scans desc --掃描行在一定範圍之內,但是是按照降序的方式
11.inlist iterator --在in謂詞中爲一個值執行一次或者多次操作
13 intersection --將兩個結果集合併成一個集,並返回在它們之間出現的共同的值
14 merger join --提供共同值,用來連接兩個結果集的結果。是內連接
output --外
anit --反
seml --半
15 nested loops --該操作涉及到2個子操作,第一操作個返回一個行集,被用於行集中的每一行,執行第二個子操作。
output --用於執行外部套嵌套循環
16 partition [分區] --執行一或者多個分區操作,partition-start,partition-stop將提供分區的範圍
singnal --顯示操作將在單個分區上執行
iterator --在許多個分區中執行
all --顯示操作將在所有分區上執行
inlist --顯示操作在分區上執行,並用IN謂詞驅動
17 projection --採用多個查詢作爲輸入,並返回單個記錄集。常和intersection,minus, unqie使用
18 sort
aggregate --在行集上採用分組函數
unique --對行集排序,去掉重複的行
join -- 和merger相同
group up -- 分組排序
orday by --按照orday by進行排序
19 table access
full --顯示指定表中的所有行
cluster --與特定索引鍵進行匹配的所有行
hash --散列
by rowid --顯示oracle表將從rowid提取
20 unqie 顯示兩個集,並去掉重複行
21 view 產生視圖,並返回結果行集。