oracle 表之間的鏈接

  排序 - - 合併鏈接(Sort Merge Join, SMJ):
  a) 對於非等值鏈接,這種鏈接方式的效率是比較高的。
  b) 若是在關聯的列上都有索引,效果更好。
  c) 對於將2個較大的row source作鏈接,該鏈接方法比NL鏈接要好一些。
  d) 可是若是sort merge返回的row source過大,則又會致使使用過多的rowid在表中查詢數據時,數據庫性能降低,由於過多的I/O.

  嵌套循環(Nested Loops, NL):
  a) 若是driving row source(外部表)比較小,而且在inner row source(內部表)上有惟一索引,或有高選擇性非惟一索引時,使用這種方法能夠獲得較好的效率。
  b) NESTED LOOPS有其它鏈接方法沒有的的一個優勢是:能夠先返回已經鏈接的行,而沒必要等待全部的鏈接操做處理完才返回數據,這能夠實現快速的響應時間。

  哈希鏈接(Hash Join, HJ):
  a) 這種方法是在oracle7後來引入的,使用了比較先進的鏈接理論,通常來講,其效率應該好於其它2種鏈接,可是這種鏈接只能用在CBO優化器中,並且須要設置合適的hash_area_size參數,才能取得較好的性能。
  b) 在2個較大的row source之間鏈接時會取得相對較好的效率,在一個row source較小時則能取得更好的效率。
  c) 只能用於等值鏈接中
 
  Oracle執行計劃的相關概念:

  Rowid:系統給oracle數據的每行附加的一個僞列,包含數據表名稱,數據庫id,存儲數據庫id以及一個流水號等信息,rowid在行的生命週期內惟一。
  Recursive sql:爲了執行用戶語句,系統附加執行的額外操做語句,譬如對數據字典的維護等。
  Row source(行源):oracle執行步驟過程當中,由上一個操做返回的符合條件的行的集合。
  Predicate(謂詞):where後的限制條件。
  Driving table(驅動表):又稱爲鏈接的外層表,主要用於嵌套與hash鏈接中。通常來講是將應用限制條件後,返回較少行源的表做爲驅動表。在後面的描述中,將driving table稱爲鏈接操做的row source 1。
  Probed table(被探查表):鏈接的內層表,在咱們從driving table獲得具體的一行數據後,在probed table中尋找符合條件的行,因此該表應該爲較大的row source,而且對應鏈接條件的列上應該有索引。在後面的描述中,通常將該表稱爲鏈接操做的row source 2.
  Concatenated index(組合索引):一個索引若是由多列構成,那麼就稱爲組合索引,組合索引的第一列爲引導列,只有謂詞中包含引導列時,索引纔可用。
  可選擇性:表中某列的不一樣數值數量/表的總行數若是接近於1,則列的可選擇性爲高。

  Oracle訪問數據的存取方法:
 
  Full table scans, FTS(全表掃描):經過設置db_block_multiblock_read_count能夠設置一次IO能讀取的數據塊個數,從而有效減小全表掃描時的IO總次數,也就是經過預讀機制將將要訪問的數據塊預先讀入內存中。只有在全表掃描狀況下才能使用多塊讀操做。
  Table Access by rowed(經過rowid存取表,rowid lookup):因爲rowid中記錄了行存儲的位置,因此這是oracle存取單行數據的最快方法。
  Index scan(索引掃描index lookup):在索引中,除了存儲每一個索引的值外,索引還存儲具備此值的行對應的rowid值,索引掃描分兩步1,掃描索引獲得rowid;2,經過 rowid讀取具體數據。每步都是單獨的一次IO,因此若是數據經限制條件過濾後的總量大於原表總行數的5%-10%,則使用索引掃描效率降低不少。而若是結果數據可以所有在索引中找到,則能夠避免第二步操做,從而加快檢索速度。
  根據索引類型與where限制條件的不一樣,有4種類型的索引掃描:
  Index unique scan(索引惟一掃描):存在unique或者primary key的狀況下,返回單個rowid數據內容。
  Index range scan(索引範圍掃描):1,在惟一索引上使用了range操做符(>,<,<>,>=,<=,between);2,在組合索引上,只使用部分列進行查詢;3,對非惟一索引上的列進行的查詢。
  Index full scan(索引全掃描):須要查詢的數據從索引中能夠所有獲得。
  Index fast full scan(索引快速掃描):與index full scan相似,可是這種方式下不對結果進行排序。

  目前爲止,典型的鏈接類型有3種:
 
  Sort merge join(SMJ排序-合併鏈接):首先生產driving table須要的數據,而後對這些數據按照鏈接操做關聯列進行排序;而後生產probed table須要的數據,而後對這些數據按照與driving table對應的鏈接操做列進行排序;最後兩邊已經排序的行被放在一塊兒執行合併操做。排序是一個費時、費資源的操做,特別對於大表。因此smj一般不是一個特別有效的鏈接方法,可是若是driving table和probed table都已經預先排序,則這種鏈接方法的效率也比較高。
  Nested loops(NL嵌套循環):鏈接過程就是將driving table和probed table進行一次嵌套循環的過程。就是用driving table的每一行去匹配probed table 的全部行。Nested loops能夠先返回已經鏈接的行,而沒必要等待全部的鏈接操做處理完成才返回數據,這能夠實現快速的響應時間。
  Hash join(哈希鏈接):較小的row source被用來構建hash table與bitmap,第二個row source用來被hashed,並與第一個row source生產的hash table進行匹配。以便進行進一步的鏈接。當被構建的hash table與bitmap能被容納在內存中時,這種鏈接方式的效率極高。但須要設置合適的hash_area_size參數且只能用於等值鏈接中。
  另外,還有一種鏈接類型:Cartesian product(笛卡爾積):表的每一行依次與另一表的全部行匹配,通常狀況下,儘可能避免使用。
相關文章
相關標籤/搜索