sqldeveloper的查看執行計劃快捷鍵F10

簡介:
?? ?本文全面詳細介紹oracle執行計劃的相關的概念,訪問數據的存取方法,表之間的連接等內容。
?? ?并有總結和概述,便于理解與記憶!
+++
目錄
---
?? ?一.相關的概念
?? ?Rowid的概念
?? ?Recursive?Sql概念
?? ?Predicate(謂詞)
?? ?DRiving Table(驅動表)
?? ?Probed Table(被探查表)
?? ?組合索引(concatenated?index)
?? ?可選擇性(selectivity)

?? ?二.oracle訪問數據的存取方法
?? ?1) 全表掃描(Full Table Scans, FTS)
?? ?2) 通過ROWID的表存取(Table Access by ROWID或rowid lookup)
?? ?3)索引掃描(Index Scan或index lookup)有4種類型的索引掃描:
?? ? (1) 索引唯一掃描(index unique scan)
?? ? (2) 索引范圍掃描(index range scan)
?? ? ? ? ? 在非唯一索引上都使用索引范圍掃描。使用index rang scan的3種情況:
?? ?   ?(a) 在唯一索引列上使用了range操作符(> < <> >= <= between)
?? ?   ?(b) 在組合索引上,只使用部分列進行查詢,導致查詢出多行
?? ?   ?(c) 對非唯一索引列上進行的任何查詢。  
?? ? (3) 索引全掃描(index full scan)
?? ? (4) 索引快速掃描(index fast full scan)

?? ?三、表之間的連接

?? ?1,排序 - - 合并連接(Sort Merge Join, SMJ)
?? ?2,嵌套循環(Nested Loops, NL)
?? ?3,哈希連接(Hash Join, HJ)
?? ?另外,笛卡兒乘積(Cartesian Product)

?? ?總結Oracle連接方法
?? ?
?? ?Oracle執行計劃總結概述

+++

  
一.相關的概念

  Rowid的概念:rowid是一個偽列,既然是偽列,那么這個列就不是用戶定義,而是系統自己給加上的。 對每個表都有一個rowid的偽列,但是表中并不物理存儲ROWID列的值。不過你可以像使用其它列那樣使用它,但是不能刪除改列,也不能對該列的值進行 修改、插入。一旦一行數據插入數據庫,則rowid在該行的生命周期內是唯一的,即即使該行產生行遷移,行的rowid也不會改變。
  
Recursive SQL概念
:有時為了執行用戶發出的一個sql語句,Oracle必須執行一些額外的語句,我們將這些額外的語句稱之為''recursive calls''或''recursive SQL statements''.如當一個DDL語句發出后,ORACLE總是隱含的發出一些recursive SQL語句,來修改數據字典信息,以便用戶可以成功的執行該DDL語句。當需要的數據字典信息沒有在共享內存中時,經常會發生Recursive calls,這些Recursive calls會將數據字典信息從硬盤讀入內存中。用戶不比關心這些recursive SQL語句的執行情況,在需要的時候,ORACLE會自動的在內部執行這些語句。當然DML語句與SELECT都可能引起recursive SQL.簡單的說,我們可以將觸發器視為recursive SQL.
  Row Source(行源):用在查詢中,由上一操作返回的符合條件的行的集合,即可以是表的全部行數據的集合;也可以是表的部分行數據的集合;也可以為對上2個row source進行連接操作(如join連接)后得到的行數據集合。
  
Predicate(謂詞)
:一個查詢中的WHERE限制條件
  
Driving Table(驅動表)
:該表又稱為外層表(OUTER TABLE)。這個概念用于嵌套與HASH連接中。如果該row source返回較多的行數據,則對所有的后續操作有負面影響。注意此處雖然翻譯為驅動表,但實際上翻譯為驅動行源(driving row source)更為確切。一般說來,是應用查詢的限制條件后,返回較少行源的表作為驅動表,所以如果一個大表在WHERE條件有有限制條件(如等值限 制),則該大表作為驅動表也是合適的,所以并不是只有較小的表可以作為驅動表,正確說法應該為應用查詢的限制條件后,返回較少行源的表作為驅動表。在執行 計劃中,應該為靠上的那個row source,后面會給出具體說明。在我們后面的描述中,一般將該表稱為連接操作的row source 1.
  
Probed Table(被探查表)
:該表又稱為內層表(INNER TABLE)。在我們從驅動表中得到具體一行的數據后,在該表中尋找符合連接條件的行。所以該表應當為大表(實際上應該為返回較大row source的表)且相應的列上應該有索引。在我們后面的描述中,一般將該表稱為連接操作的row source 2.
  
組合索引(concatenated index)
:由多個列構成的索引,如create index idx_emp on emp(col1, col2, col3, ……),則我們稱idx_emp索引為組合索引。在組合索引中有一個重要的概念:引導列(leading column),在上面的例子中,col1列為引導列。當我們進行查詢時可以使用“where col1 = ? ”,也可以使用“where col1 = ? and col2 = ?”,這樣的限制條件都會使用索引,但是“where col2 = ? ”查詢就不會使用該索引。所以限制條件中包含先導列時,該限制條件才會使用該組合索引。
  
可選擇性(selectivity):比較一下列中唯一鍵的數量和表中的行數,就可以判斷該列的可選擇性。 如果該列的“唯一鍵的數量/表中的行數”的比值越接近1,則該列的可選擇性越高,該列就越適合創建索引,同樣索引的可選擇性也越高。在可選擇性高的列上進 行查詢時,返回的數據就較少,比較適合使用索引查詢。

  二.oracle訪問數據的存取方法

  1) 全表掃描(Full Table Scans, FTS)
  為實現全表掃描,Oracle讀取表中所有的行,并檢查每一行是否滿足語句的WHERE限制條件一個多塊讀操作可以使一次I/O能讀取多塊數據塊(db_block_multiblock_read_count參數設定),而不是只讀取一個數據塊,這極大的減 少了I/O總次數,提高了系統的吞吐量,所以利用多塊讀的方法可以十分高效地實現全表掃描,而且只有在全表掃描的情況下才能使用多塊讀操作。在這種訪問模 式下,每個數據塊只被讀一次。
  使用FTS的前提條件:在較大的表上不建議使用全表掃描,除非取出數據的比較多,超過總量的5% —— 10%,或你想使用并行查詢功能時。
  使用全表掃描的例子:
?
  SQL> explain plan for select * from dual;
  Query Plan
  -----------------------------------------
  SELECT STATEMENT[CHOOSE] Cost=
  TABLE ACCESS FULL DUAL

  2) 通過ROWID的表存取(Table Access by ROWID或rowid lookup)
  行的ROWID指出了該行所在的數據文件、數據塊以及行在該塊中的位置,所以通過ROWID來存取數據可以快速定位到目標數據上,是Oracle存取單行數據的最快方法。
  這種存取方法不會用到多塊讀操作,一次I/O只能讀取一個數據塊。我們會經常在執行計劃中看到該存取方法,如通過索引查詢數據。
  使用ROWID存取的方法:?
  SQL> explain plan for select * from dept where rowid = ''AAAAyGAADAAAAATAAF'';
?
  Query Plan
  ------------------------------------
  SELECT STATEMENT [CHOOSE] Cost=1
  TABLE ACCESS BY ROWID DEPT [ANALYZED]

  3)索引掃描(Index Scan或index lookup)
  我們先通過index查找到數據對應的rowid值(對于非唯一索引可能返回多個rowid值),然后根據rowid直接從表中得到具體的數據,這 種查找方式稱為索引掃描或索引查找(index lookup)。一個rowid唯一的表示一行數據,該行對應的數據塊是通過一次i/o得到的,在此情況下該次i/o只會讀取一個數據庫塊。
  在索引中,除了存儲每個索引的值外,索引還存儲具有此值的行對應的ROWID值。
  索引掃描可以由2步組成:
  (1) 掃描索引得到對應的rowid值。
  (2) 通過找到的rowid從表中讀出具體的數據。
  每步都是單獨的一次I/O,但是對于索引,由于經常使用,絕大多數都已經CACHE到內存中,所以第1步的 I/O經常是邏輯I/O,即數據可以從內存中得到。但是對于第2步來說,如果表比較大,則其數據不可能全在內存中,所以其I/O很有可能是物理I/O,這 是一個機械操作,相對邏輯I/O來說,是極其費時間的。所以如果多大表進行索引掃描,取出的數據如果大于總量的5% —— 10%,使用索引掃描會效率下降很多。如下列所示:
  SQL> explain plan for select empno, ename from emp where empno=10;
  Query Plan
  ------------------------------------
  SELECT STATEMENT [CHOOSE] Cost=1
  TABLE ACCESS BY ROWID EMP [ANALYZED]
  INDEX UNIQUE SCAN EMP_I1

  但是如果查詢的數據能全在索引中找到,就可以避免進行第2步操作,避免了不必要的I/O,此時即使通過索引掃描取出的數據比較多,效率還是很高的
  SQL> explain plan for select empno from emp where empno=10;-- 只查詢empno列值
  Query Plan
  ------------------------------------
  SELECT STATEMENT [CHOOSE] Cost=1
  INDEX UNIQUE SCAN EMP_I1

  進一步講,如果sql語句中對索引列進行排序,因為索引已經預先排序好了,所以在執行計劃中不需要再對索引列進行排序
  SQL> explain plan for select empno, ename from emp
  where empno > 7876 order by empno;
  Query Plan
  --------------------------------------------------------------------------------
  SELECT STATEMENT[CHOOSE] Cost=1
  TABLE ACCESS BY ROWID EMP [ANALYZED]
  INDEX RANGE SCAN EMP_I1 [ANALYZED]

  從這個例子中可以看到:因為索引是已經排序了的,所以將按照索引的順序查詢出符合條件的行,因此避免了進一步排序操作。
  根據索引的類型與where限制條件的不同,有4種類型的索引掃描:
  索引唯一掃描(index unique scan)
  索引范圍掃描(index range scan)
  索引全掃描(index full scan)
  索引快速掃描(index fast full scan)

  (1) 索引唯一掃描(index unique scan)
  通過唯一索引查找一個數值經常返回單個ROWID.如果存在UNIQUE 或PRIMARY KEY 約束(它保證了語句只存取單行)的話,Oracle經常實現唯一性掃描。
  使用唯一性約束的例子:
  SQL> explain plan for
  select empno,ename from emp where empno=10;
  Query Plan
  ------------------------------------
  SELECT STATEMENT [CHOOSE] Cost=1
  TABLE ACCESS BY ROWID EMP [ANALYZED]
  INDEX UNIQUE SCAN EMP_I1

  (2) 索引范圍掃描(index range scan)
  使用一個索引存取多行數據,在唯一索引上使用索引范圍掃描的典型情況下是在謂詞(where限制條件)中使用了范圍操作符(如>、<、<>、>=、<=、between)
  使用索引范圍掃描的例子:
  SQL> explain plan for select empno,ename from emp
  where empno > 7876 order by empno;
  Query Plan
  --------------------------------------------------------------------------------
  SELECT STATEMENT[CHOOSE] Cost=1
  TABLE ACCESS BY ROWID EMP [ANALYZED]
  INDEX RANGE SCAN EMP_I1 [ANALYZED]

  在非唯一索引上,謂詞col = 5可能返回多行數據,所以在非唯一索引上都使用索引范圍掃描。
  使用index rang scan的3種情況:
  (a) 在唯一索引列上使用了range操作符(> < <> >= <= between)
  (b) 在組合索引上,只使用部分列進行查詢,導致查詢出多行
  (c) 對非唯一索引列上進行的任何查詢。

  (3) 索引全掃描(index full scan)
  與全表掃描對應,也有相應的全索引掃描。而且此時查詢出的數據都必須從索引中可以直接得到。
  全索引掃描的例子:
  An Index full scan will not perform. single block i/o''s and so it may prove to be inefficient.
  e.g.
  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;
  Query Plan
  --------------------------------------------------------------------------------
  SELECT STATEMENT[CHOOSE] Cost=26
  INDEX FULL SCAN BE_IX [ANALYZED]

  (4) 索引快速掃描(index fast full scan)
  掃描索引中的所有的數據塊,與 index full scan很類似,但是一個顯著的區別就是它不對查詢出的數據進行排序,即數據不是以排序順序被返回。在這種存取方法中,可以使用多塊讀功能,也可以使用并行讀入,以便獲得最大吞吐量與縮短執行時間。
  索引快速掃描的例子:
  BE_IX索引是一個多列索引: big_emp (empno,ename)
  SQL> explain plan for select empno,ename from big_emp;
  Query Plan
  ------------------------------------------
  SELECT STATEMENT[CHOOSE] Cost=1
  INDEX FAST FULL SCAN BE_IX [ANALYZED]

  只選擇多列索引的第2列:
  SQL> explain plan for select ename from big_emp;
  Query Plan
  ------------------------------------------
  SELECT STATEMENT[CHOOSE] Cost=1
  INDEX FAST FULL SCAN BE_IX [ANALYZED]

  三、表之間的連接

  Join是一種試圖將兩個表結合在一起的謂詞,一次只能連接2個表,表連接也可以被稱為表關聯。在后面的敘 述中,我們將會使用“row source”來代替“表”,因為使用row source更嚴謹一些,并且將參與連接的2個row source分別稱為row source1和row source 2.Join過程的各個步驟經常是串行操作,即使相關的row source可以被并行訪問,即可以并行的讀取做join連接的兩個row source的數據,但是在將表中符合限制條件的數據讀入到內存形成row source后,join的其它步驟一般是串行的。有多種方法可以將2個表連接起來,當然每種方法都有自己的優缺點,每種連接類型只有在特定的條件下才會 發揮出其最大優勢。
  row source(表)之間的連接順序對于查詢的效率有非常大的影響。通過首先存取特定的表,即將該表作為驅動表,這樣可以先應用某些限制條件,從而得到一個 較小的row source,使連接的效率較高,這也就是我們常說的要先執行限制條件的原因。一般是在將表讀入內存時,應用where子句中對該表的限制條件。
  根據2個row source的連接條件的中操作符的不同,可以將連接分為等值連接(如WHERE A.COL3 = B.COL4)、非等值連接(WHERE A.COL3 > B.COL4)、外連接(WHERE A.COL3 = B.COL4(+))。上面的各個連接的連接原理都基本一樣,所以為了簡單期間,下面以等值連接為例進行介紹。
  在后面的介紹中,都以以下Sql為例進行說明:
  SELECT A.COL1, B.COL2
  FROM A, B
  WHERE A.COL3 = B.COL4;
  假設A表為Row Soruce1,則其對應的連接操作關聯列為COL 3;
  B表為Row Soruce2,則其對應的連接操作關聯列為COL 4;

  連接類型:
  目前為止,無論連接操作符如何,典型的連接類型共有3種:
  
排序 - - 合并連接(Sort Merge Join (SMJ) )
  嵌套循環(Nested Loops (NL) )
  哈希連接(Hash Join)
  另外,還有一種Cartesian product(笛卡爾積),一般情況下,盡量避免使用。

  1,排序 - - 合并連接(Sort Merge Join, SMJ)
  內部連接過程
  1) 首先生成row source1需要的數據,然后對這些數據按照連接操作關聯列(如A.col3)進行排序。
  2) 隨后生成row source2需要的數據,然后對這些數據按照與sort source1對應的連接操作關聯列(如B.col4)進行排序。
  3) 最后兩邊已排序的行被放在一起執行合并操作,即將2個row source按照連接條件連接起來

  下面是連接步驟的圖形表示:
  MERGE
  /\
  SORTSORT
  ||
  Row Source 1Row Source 2

  如果row source已經在連接關聯列上被排序,則該連接操作就不需要再進行sort操作,這樣可以大大提高這種連接操作的連接速度,因為排序是個極其費資源的操 作,特別是對于較大的表。預先排序的row source包括已經被索引的列(如a.col3或b.col4上有索引)或row source已經在前面的步驟中被排序了。盡管合并兩個row source的過程是串行的,但是可以并行訪問這兩個row source(如并行讀入數據,并行排序)。
  SMJ連接的例子:
  SQL> explain plan for
  select
/*+ ordered */
e.deptno, d.deptno
  from emp e, dept d
  where e.deptno = d.deptno
  order by e.deptno, d.deptno;
  Query Plan
  -------------------------------------
  SELECT STATEMENT [CHOOSE] Cost=17
  
MERGE JOIN

  SORT JOIN
  TABLE ACCESS FULL EMP [ANALYZED]
  SORT JOIN
  TABLE ACCESS FULL DEPT [ANALYZED]

  排序是一個費時、費資源的操作,特別對于大表。基于這個原因,SMJ經常不是一個特別有效的連接方法,但是如果2個row source都已經預先排序,則這種連接方法的效率也是蠻高的。

  2,嵌套循環(Nested Loops, NL)
  這個連接方法有驅動表(外部表)的概念。其實,該連接過程就是一個2層嵌套循環,所以外層循環的次數越少越好,這也就是我們為什么將小表或返回較小 row source的表作為驅動表(用于外層循環)的理論依據。但是這個理論只是一般指導原則,因為遵循這個理論并不能總保證使語句產生的I/O次數最少。有時 不遵守這個理論依據,反而會獲得更好的效率。如果使用這種方法,決定使用哪個表作為驅動表很重要。有時如果驅動表選擇不正確,將會導致語句的性能很差、很差。
  內部連接過程:
  Row source1的Row 1 —— Probe ->Row source 2
  Row source1的Row 2 —— Probe ->Row source 2
  Row source1的Row 3 —— Probe ->Row source 2
  ……。
  Row source1的Row n —— Probe ->Row source 2

  從內部連接過程來看,需要用row source1中的每一行,去匹配row source2中的所有行,所以此時保持row source1盡可能的小與高效的訪問row source2(一般通過索引實現)是影響這個連接效率的關鍵問題。這只是理論指導原則,目的是使整個連接操作產生最少的物理I/O次數,而且如果遵守這 個原則,一般也會使總的物理I/O數最少。但是如果不遵從這個指導原則,反而能用更少的物理I/O實現連接操作,那盡管違反指導原則吧!因為最少的物理 I/O次數才是我們應該遵從的真正的指導原則,在后面的具體案例分析中就給出這樣的例子。
  在上面的連接過程中,我們稱Row source1為驅動表或外部表。Row Source2被稱為被探查表或內部表。
  在NESTED LOOPS連接中,Oracle讀取row source1中的每一行,然后在row sourc2中檢查是否有匹配的行,所有被匹配的行都被放到結果集中,然后處理row source1中的下一行。這個過程一直繼續,直到row source1中的所有行都被處理。這是從連接操作中可以得到第一個匹配行的最快的方法之一,這種類型的連接可以用在需要快速響應的語句中,以響應速度為 主要目標。
  如果driving row source(外部表)比較小,并且在inner row source(內部表)上有唯一索引,或有高選擇性非唯一索引時,使用這種方法可以得到較好的效率。NESTED LOOPS有其它連接方法沒有的的一個優點是:可以先返回已經連接的行,而不必等待所有的連接操作處理完才返回數據,這可以實現快速的響應時間。
  如果不使用并行操作,最好的驅動表是那些應用了where 限制條件后,可以返回較少行數據的的表,所以大表也可能稱為驅動表,關鍵看限制條件。對于并行查詢,我們經常選擇大表作為驅動表,因為大表可以充分利用并 行功能。當然,有時對查詢使用并行操作并不一定會比查詢不使用并行操作效率高,因為最后可能每個表只有很少的行符合限制條件,而且還要看你的硬件配置是否 可以支持并行(如是否有多個CPU,多個硬盤控制器),所以要具體問題具體對待。
  NL連接的例子:
  SQL> explain plan for
  select a.dname,b.sql
  from dept a,emp b
  where a.deptno = b.deptno;
  Query Plan
  -------------------------
  SELECT STATEMENT [CHOOSE] Cost=5
  
NESTED LOOPS

  TABLE ACCESS FULL DEPT [ANALYZED]
  TABLE ACCESS FULL EMP [ANALYZED]

  3,哈希連接(Hash Join, HJ)
  這種連接是在oracle 7.3以后引入的,從理論上來說比NL與SMJ更高效,而且只用在CBO優化器中。
  較小的row source被用來構建hash table與bitmap,第2個row source被用來被hansed,并與第一個row source生成的hash table進行匹配,以便進行進一步的連接。Bitmap被用來作為一種比較快的查找方法,來檢查在hash table中是否有匹配的行。特別的,當hash table比較大而不能全部容納在內存中時,這種查找方法更為有用。這種連接方法也有NL連接中所謂的驅動表的概念,被構建為hash table與bitmap的表為驅動表,當被構建的hash table與bitmap能被容納在內存中時,這種連接方式的效率極高。

  HASH連接的例子:
  SQL> explain plan for
  select
/*+ use_hash(emp) */
empno
  from emp, dept
  where emp.deptno = dept.deptno;
  Query Plan
  ----------------------------
  SELECT STATEMENT[CHOOSE] Cost=3
  
HASH JOIN

  TABLE ACCESS FULL DEPT
  TABLE ACCESS FULL EMP

  要使哈希連接有效,需要設置HASH_JOIN_ENABLED=TRUE,缺省情況下該參數為TRUE,另外,不要忘了還要設置 hash_area_size參數,以使哈希連接高效運行,因為哈希連接會在該參數指定大小的內存中運行,過小的參數會使哈希連接的性能比其他連接方式還 要低。

  另外,笛卡兒乘積(Cartesian Product)
  當兩個row source做連接,但是它們之間沒有關聯條件時,就會在兩個row source中做笛卡兒乘積,這通常由編寫代碼疏漏造成(即程序員忘了寫關聯條件)。笛卡爾乘積是一個表的每一行依次與另一個表中的所有行匹配。在特殊情況下我們可以使用笛卡兒乘積,如在星形連接中,除此之外,我們要盡量不使用笛卡兒乘積,否則,自己想結果是什么吧!
  注意在下面的語句中,在2個表之間沒有連接。
  SQL> explain plan for
  select emp.deptno,dept,deptno
  from emp,dept
  Query Plan
  ------------------------
  SLECT STATEMENT [CHOOSE] Cost=5
  
MERGE JOIN CARTESIAN
  TABLE ACCESS FULL DEPT
  SORT JOIN
  TABLE ACCESS FULL EMP

  CARTESIAN關鍵字指出了在2個表之間做笛卡爾乘積。假如表emp有n行,dept表有m行,笛卡爾乘積的結果就是得到n * m行結果。

  最后,總結一下,在哪種情況下用哪種連接方法比較好:

  排序 - - 合并連接(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執行計劃的概述

  ---

  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,對非唯一索引上的列進行的查詢。
  I
ndex 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(笛卡爾積):表的每一行依次與另外一表的所有行匹配,一般情況下,盡量避免使用。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/387898.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/387898.shtml
英文地址,請注明出處:http://en.pswp.cn/news/387898.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

大數據技術 學習之旅_為什么聚焦是您數據科學之旅的關鍵

大數據技術 學習之旅David Robinson, a data scientist, has said the following quotes:數據科學家David Robinson曾說過以下話&#xff1a; “When you’ve written the same code 3 times, write a function.”“當您編寫了3次相同的代碼時&#xff0c;請編寫一個函數。” …

SQL 語句

去重字段里的值 SELECT DISTINCT cat_id,goods_sn,repay FROM ecs_goods where cat_id ! 20014 刪除除去 去重字段 DELETE FROM ecs_goods where goods_id NOT IN ( select bid from (select min(goods_id) as bid from ecs_goods group by cat_id,goods_sn,repay) as b );轉…

無監督學習 k-means_無監督學習-第4部分

無監督學習 k-means有關深層學習的FAU講義 (FAU LECTURE NOTES ON DEEP LEARNING) These are the lecture notes for FAU’s YouTube Lecture “Deep Learning”. This is a full transcript of the lecture video & matching slides. We hope, you enjoy this as much as …

vCenter 升級錯誤 VCSServiceManager 1603

近日&#xff0c;看到了VMware發布的vCenter 6.7 Update 1b的更新消息。其中有一條比較震撼。有誤刪所有VM的概率&#xff0c;這種BUG誰也承受不起。Removing a virtual machine folder from the inventory by using the vSphere Client might delete all virtual machinesIn t…

day28 socketserver

1. socketserver 多線程用的 例 import socket import timeclientsocket.socket() client.connect(("127.0.0.1",9000))while 1:cmdinput("請輸入指令")client.send(cmd.encode("utf-8"))from_server_msgclient.recv(1024).decode("utf…

車牌識別思路

本文源自我之前花了2天時間做的一個簡單的車牌識別系統。那個項目&#xff0c;時間太緊&#xff0c;樣本也有限&#xff0c;達不到對方要求的95%識別率&#xff08;主要對于車牌來說&#xff0c;D,0&#xff0c;O&#xff0c;I&#xff0c;1等等太相似了。然后&#xff0c;漢字…

深度學習算法原理_用于對象檢測的深度學習算法的基本原理

深度學習算法原理You just got a new drone and you want it to be super smart! Maybe it should detect whether workers are properly wearing their helmets or how big the cracks on a factory rooftop are.您剛剛擁有一架新無人機&#xff0c;并希望它變得超級聰明&…

【python】numpy庫linspace相同間隔采樣 詳解

linspace可以用來實現相同間隔的采樣&#xff1b; numpy.linspace(start,stop,num50,endpointTrue,retstepFalse, dtypeNone) 返回num均勻分布的樣本&#xff0c;在[start, stop]。 Parameters(參數): start : scalar(標量) The starting value of the sequence(序列的起始點)…

Spring整合JMS——基于ActiveMQ實現(一)

Spring整合JMS——基于ActiveMQ實現&#xff08;一&#xff09; 1.1 JMS簡介 JMS的全稱是Java Message Service&#xff0c;即Java消息服務。它主要用于在生產者和消費者之間進行消息傳遞&#xff0c;生產者負責產生消息&#xff0c;而消費者負責接收消息。把它應用到實際的…

軟件本地化 pdf_軟件本地化與標準翻譯

軟件本地化 pdfSoftware has become such an essential part of our world that it’s impossible to imagine a life without it. There’s hardly a service or product around us that wasn’t created with software or that runs on software.軟件已成為我們世界的重要組成…

CentOS7+CDH5.14.0安裝全流程記錄,圖文詳解全程實測-8CDH5安裝和集群配置

Cloudera Manager Server和Agent都啟動以后&#xff0c;就可以進行CDH5的安裝配置了。 準備文件 從 http://archive.cloudera.com/cdh5/parcels/中下載CDH5.14.0的相關文件 把CDH5需要的安裝文件放到主節點上&#xff0c;新建目錄為/opt/cloudera/parcel-repo把我們之前下載的…

node.js安裝部署測試

&#xff08;一&#xff09;安裝配置&#xff1a; 1&#xff1a;從nodejs.org下載需要的版本 2&#xff1a;直接安裝&#xff0c;默認設置 &#xff0c;默認安裝在c:\program files\nodejs下。 3&#xff1a;更改npm安裝模塊的默認目錄 &#xff08;默認目錄在安裝目錄下的node…

數據庫不停機導數據方案_如何計算數據停機成本

數據庫不停機導數據方案In addition to wasted time and sleepless nights, data quality issues lead to compliance risks, lost revenue to the tune of several million dollars per year, and erosion of trust — but what does bad data really cost your company? I’…

luogu4159 迷路 (矩陣加速)

考慮如果只有距離為1的邊&#xff0c;那我用在時間i到達某個點的狀態數矩陣 乘上轉移矩陣&#xff08;就是邊的鄰接矩陣&#xff09;&#xff0c;就能得到i1時間的 然后又考慮到邊權只有1~9&#xff0c;那可以把邊拆成只有距離為1的 具體做法是一個點拆成9個然后串聯 1 #includ…

社群系統ThinkSNS+ V2.2-V2.3升級教程

WARNING本升級指南僅適用于 2.2 版本升級至 2.3 版本&#xff0c;如果你并非 2.2 版本&#xff0c;請查看其他升級指南&#xff0c;Plus 程序不允許跨版本升級&#xff01;#更新代碼預計耗時&#xff1a; 2 小時這是你自我操作的步驟&#xff0c;確認將你的 2.2 版本代碼升級到…

BZOJ4881 線段游戲(二分圖+樹狀數組/動態規劃+線段樹)

相當于將線段劃分成兩個集合使集合內線段不相交&#xff0c;并且可以發現線段相交等價于逆序對。也即要將原序列劃分成兩個單增序列。由dilworth定理&#xff0c;如果存在長度>3的單減子序列&#xff0c;無解&#xff0c;可以先判掉。 這個時候有兩種顯然的暴力。 將點集劃分…

activemq部署安裝

一、架構和技術介紹 1、簡介 ActiveMQ 是Apache出品&#xff0c;最流行的&#xff0c;能力強勁的開源消息總線。完全支持JMS1.1和J2EE 1.4規范的 JMS Provider實現 2、activemq的特性 1. 多種語言和協議編寫客戶端。語言: Java, C, C, C#, Ruby, Perl, Python, PHP。應用協議: …

python初學者_面向初學者的20種重要的Python技巧

python初學者Python is among the most widely used market programming languages in the world. This is because of a variety of driving factors:Python是世界上使用最廣泛的市場編程語言之一。 這是由于多種驅動因素&#xff1a; It’s simple to understand. 很容易理解…

主串與模式串的匹配

主串與模式串的匹配 &#xff08;1&#xff09;BF算法&#xff1a; BF算法比較簡單直觀&#xff0c;其匹配原理是主串S.ch[i]和模式串T.ch[j]比較&#xff0c;若相等&#xff0c;則i和j分別指示串中的下一個位置&#xff0c;繼續比較后續字符&#xff0c;若不相等&#xff0c;從…

什么是 DDoS 攻擊?

歡迎訪問網易云社區&#xff0c;了解更多網易技術產品運營經驗。 全稱Distributed Denial of Service&#xff0c;中文意思為“分布式拒絕服務”&#xff0c;就是利用大量合法的分布式服務器對目標發送請求&#xff0c;從而導致正常合法用戶無法獲得服務。通俗點講就是利用網絡…