偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Oracle優(yōu)化查詢中所用到的語句有哪些?

數(shù)據(jù)庫 Oracle
我們今天主要和大家分享的是Oracle優(yōu)化查詢的實(shí)際操作步驟,以及在實(shí)際操作中那些的語句是我們所能用到的,以下就是文章的具體內(nèi)容的介紹。

以下的文章主要講述的是Oracle優(yōu)化查詢的實(shí)際操作我們首先是假設(shè)LARGE_TABLE是一個(gè)表(較大型),而且username列上是沒有相關(guān)索引的,那么它在實(shí)際的操作中要用到的語句有那些?下面就是對(duì)其語句的描述:

 

  1. SQL> SELECT * FROM LARGE_TABLE where USERNAME = ‘TEST';   
  2. Query Plan   
  3. SELECT STATEMENT Optimizer=CHOOSE (Cost=1234 Card=1 Bytes=14)   
  4. TABLE ACCESS FULL LARGE_TABLE [:Q65001] [ANALYZED] 

在這個(gè)例子中,TABLE ACCESS FULL LARGE_TABLE是第一個(gè)操作,意思是在LARGE_TABLE表上做全表掃描。當(dāng)這個(gè)操作完成之后,產(chǎn)生的row source中的數(shù)據(jù)被送往下一步驟進(jìn)行處理,在此例中,SELECT STATEMENT操作是這個(gè)Oracle優(yōu)化查詢語句的最后一步。

Optimizer=CHOOSE 指明這個(gè)查詢的optimizer_mode,即optimizer_mode初始化參數(shù)指定的值,它并不是指語句執(zhí)行時(shí)真的使用了該優(yōu)化器。決定該語句使用何種優(yōu)化器的唯一方法是看后面的cost部分。例如,如果給出的是下面的形式,則表明使用的是CBO優(yōu)化器,此處的cost表示優(yōu)化器認(rèn)為該執(zhí)行計(jì)劃的代價(jià):

 

  1. SELECT STATEMENT Optimizer=CHOOSE (Cost=1234 Card=1 Bytes=14

然而假如執(zhí)行計(jì)劃中給出的是類似下面的信息,則表明是使用RBO優(yōu)化器,因?yàn)閏ost部分的值為空,或者壓根就沒有cost部分。

  1. SELECT STATEMENT Optimizer=CHOOSE Cost=   
  2. SELECT STATEMENT Optimizer=CHOOSE 

這樣我們從Optimizer后面的信息中可以得出執(zhí)行該語句時(shí)到底用了什么樣的優(yōu)化器。特別的,如果Optimizer=ALL_ROWS| FIRST_ROWS| FIRST_ROWS_n,則使用的是CBO優(yōu)化器;如果Optimizer=RULE,則使用的是RBO優(yōu)化器。

cost屬性的值是一個(gè)在Oracle內(nèi)部用來比較各個(gè)執(zhí)行計(jì)劃所耗費(fèi)的代價(jià)的值,從而使優(yōu)化器可以選擇最好的執(zhí)行計(jì)劃。不同語句的cost值不具有可比性,只能對(duì)同一個(gè)語句的不同執(zhí)行計(jì)劃的cost值進(jìn)行比較。

[:Q65001] 表明該部分查詢是以并行方式運(yùn)行的。里面的數(shù)據(jù)表示這個(gè)操作是由并行Oracle優(yōu)化查詢的一個(gè)slave進(jìn)程處理的,以便該操作可以區(qū)別于串行執(zhí)行的操作。

[ANALYZED] 表明操作中引用的對(duì)象被分析過了,在數(shù)據(jù)字典中有該對(duì)象的統(tǒng)計(jì)信息可以供CBO使用。

例2:

假定A、B、C都是不是小表,且在A表上一個(gè)組合索引:A(a.col1,a.col2) ,注意a.col1列為索引的引導(dǎo)列??紤]下面的查詢:

 

  1. select A.col4   
  2. from A , B , C   
  3. where B.col3 = 10 and A.col1 = B.col1 and A.col2 = C.col2 and C.col3 = 5   
  4. Execution Plan   
  5. SELECT STATEMENT Optimizer=CHOOSE   
  6. 0  MERGE JOIN   
  7. 1 SORT (JOIN)   
  8. 2  NESTED LOOPS   
  9. 3 TABLE ACCESS (FULL) OF 'B'   
  10. 3 TABLE ACCESS (BY INDEX ROWID) OF 'A'   
  11. 5  INDEX (RANGE SCAN) OF 'INX_COL12A' (NON-UNIQUE)   
  12. 1 SORT (JOIN)   
  13. 7  TABLE ACCESS (FULL) OF 'C'  
  14. Statistics   
  15. 0 recursive calls   
  16. 8 db block gets   
  17. 6 consistent gets   
  18. 0 physical reads   
  19. 0 redo size   
  20. 551  bytes sent via SQL*Net to client   
  21. 430  bytes received via SQL*Net from client   
  22. 2 SQL*Net roundtrips to/from client   
  23. 2 sorts (memory)   
  24. 0 sorts (disk)   
  25. 6 rows processed  

 

在表做連接時(shí),只能2個(gè)表先做連接,然后將連接后的結(jié)果作為一個(gè)row source,與剩下的表做連接,在上面的例子中,連接順序?yàn)锽與A先連接,然后再與C連接:
B  <--->  A  <--->  C
col3=10  col3=5

如果沒有執(zhí)行計(jì)劃,分析一下,上面的3個(gè)表應(yīng)該拿哪一個(gè)作為第一個(gè)驅(qū)動(dòng)表?從SQL語句看來,只有B表與C表上有限制條件,所以第一個(gè)驅(qū)動(dòng)表應(yīng)該為這2個(gè)表中的一個(gè),到底是哪一個(gè)呢?

B表有謂詞B.col3 = 10,這樣在對(duì)B表做全表掃描的時(shí)候就將where子句中的限制條件(B.col3 = 10)用上,從而得到一個(gè)較小的row source, 所以B表應(yīng)該作為第一個(gè)驅(qū)動(dòng)表。而且這樣的話,如果再與A表做關(guān)聯(lián),可以有效利用A表的索引(因?yàn)锳表的col1列為leading column)。

當(dāng)然上面的Oracle優(yōu)化查詢中C表上也有謂詞(C.col3 = 5),有人可能認(rèn)為C表作為第一個(gè)驅(qū)動(dòng)表也能獲得較好的性能。讓我們再來分析一下:如果C表作為第一個(gè)驅(qū)動(dòng)表,則能保證驅(qū)動(dòng)表生成很小的row source,但是看看連接條件A.col2 = C.col2,此時(shí)就沒有機(jī)會(huì)利用A表的索引,因?yàn)锳表的col2列不為leading column,這樣nested loop的效率很差,從而導(dǎo)致查詢的效率很差。

所以對(duì)于NL連接選擇正確的驅(qū)動(dòng)表很重要。

因此上面查詢比較好的連接順序?yàn)?B - - > A) - - > C。如果數(shù)據(jù)庫是基于代價(jià)的優(yōu)化器,它會(huì)利用計(jì)算出的代價(jià)來決定合適的驅(qū)動(dòng)表與合適的連接順序。一般來說,CBO都會(huì)選擇正確的連接順序,如果CBO選擇了比較差的連接順序,我們還可以使用Oracle提供的hints來讓CBO采用正確的連接順序。如下所示:

 

  1. select /*+ ordered */ A.col4   
  2. from B,A,C   
  3. where B.col3 = 10   
  4. and A.col1 = B.col1   
  5. and A.col2 = C.col2   
  6. and C.col3 = 5 

既然選擇正確的驅(qū)動(dòng)表這么重要,那么讓我們來看一下執(zhí)行計(jì)劃,到底各個(gè)表之間是如何關(guān)聯(lián)的,從而得到執(zhí)行計(jì)劃中哪個(gè)表應(yīng)該為驅(qū)動(dòng)表:在執(zhí)行計(jì)劃中,需要知道哪個(gè)操作是先執(zhí)行的,哪個(gè)操作是后執(zhí)行的,這對(duì)于判斷哪個(gè)表為驅(qū)動(dòng)表有用處。

判斷之前,如果對(duì)表的訪問是通過rowid,且該rowid的值是從索引掃描中得來得,則將該索引掃描先從執(zhí)行計(jì)劃中暫時(shí)去掉。然后在執(zhí)行計(jì)劃剩下的部分中,判斷執(zhí)行順序的指導(dǎo)原則就是:最右、最上的操作先執(zhí)行。具體解釋如下:

得到去除妨礙判斷的索引掃描后的執(zhí)行計(jì)劃:

  1. Execution Plan    
  2. SELECT STATEMENT Optimizer=CHOOSE   
  3. 0  MERGE JOIN   
  4. 1 SORT (JOIN)   
  5. 2  NESTED LOOPS   
  6. 3 TABLE ACCESS (FULL) OF 'B'   
  7. 3 TABLE ACCESS (BY INDEX ROWID) OF 'A'   
  8. 1 SORT (JOIN)   
  9. 7  TABLE ACCESS (FULL) OF 'C' 

看執(zhí)行計(jì)劃的第3列,即字母部分,每列值的左面有空格作為縮進(jìn)字符。在該列值左邊的空格越多,說明該列值的縮進(jìn)越多,該列值也越靠右。如上面的執(zhí)行計(jì)劃所示:第一列值為6的行的縮進(jìn)最多,即該行最靠右;第一列值為4、5的行的縮進(jìn)一樣,其靠右的程度也一樣,但是第一列值為4的行比第一列值為5的行靠上;談?wù)撋舷玛P(guān)系時(shí),只對(duì)連續(xù)的、縮進(jìn)一致的行有效。

從這個(gè)圖中我們可以看到,對(duì)于NESTED LOOPS部分,最右、最上的操作是TABLE ACCESS (FULL) OF 'B',所以這一操作先執(zhí)行,所以該操作對(duì)應(yīng)的B表為第一個(gè)驅(qū)動(dòng)表(外部表),自然,A表就為內(nèi)部表了。

從圖中還可以看出,B與A表做嵌套循環(huán)后生成了新的row source ,對(duì)該row source進(jìn)行來排序后,與C表對(duì)應(yīng)的排序了的row source(應(yīng)用了C.col3 = 5限制條件)進(jìn)行MSJ連接操作。所以從上面可以得出如下事實(shí):B表先與A表做嵌套循環(huán),然后將生成的row source與C表做排序—合并連接。

通過分析上面的執(zhí)行計(jì)劃,我們不能說C表一定在B、A表之后才被讀取,事實(shí)上,B表有可能與C表同時(shí)被讀入內(nèi)存,因?yàn)閷⒈碇械臄?shù)據(jù)讀入內(nèi)存的操作可能為并行的。事實(shí)上許多操作可能為交叉進(jìn)行的,因?yàn)镺racle讀取數(shù)據(jù)時(shí),如果就是需要一行數(shù)據(jù)也是將該行所在的整個(gè)數(shù)據(jù)塊讀入內(nèi)存,而且還有可能為多塊讀。

看執(zhí)行計(jì)劃時(shí),我們的關(guān)鍵不是看哪個(gè)操作先執(zhí)行,哪個(gè)操作后執(zhí)行,而是關(guān)鍵看表之間連接的順序(如得知哪個(gè)為驅(qū)動(dòng)表,這需要從操作的順序進(jìn)行判斷)、使用了何種類型的關(guān)聯(lián)及具體的存取路徑(如判斷是否利用了索引)

在從執(zhí)行計(jì)劃中判斷出哪個(gè)表為驅(qū)動(dòng)表后,根據(jù)我們的知識(shí)判斷該表作為驅(qū)動(dòng)表(就像上面判斷ABC表那樣)是否合適,如果不合適,對(duì)SQL語句進(jìn)行更改,使優(yōu)化器可以選擇正確的驅(qū)動(dòng)表。

對(duì)于RBO優(yōu)化器:

在Oracle文檔上說:對(duì)于RBO來說,以from 子句中從右到左的順序選擇驅(qū)動(dòng)表,即最右邊的表為第一個(gè)驅(qū)動(dòng)表,這是其英文原文:All things being equal RBO chooses the driving order by taking the tables in the FROM clause RIGHT to LEFT。

不過,在我做的測試中,從來也沒有驗(yàn)證過這種說法是正確的。我認(rèn)為,即使在RBO中,也是有一套規(guī)則來決定使用哪種連接類型和哪個(gè)表作為驅(qū)動(dòng)表,在選擇時(shí)肯定會(huì)考慮當(dāng)前索引的情況,還可能會(huì)考慮where 中的限制條件,但是肯定是與where中限制條件的位置無關(guān)。

測試 :如果我創(chuàng)建3個(gè)表:

  1. create table A(col1 number(4,0),col2 number(4,0), col4 char(30));   
  2. create table B(col1 number(4,0),col3 number(4,0), name_b char(30));   
  3. create table C(col2 number(4,0),col3 number(4,0), name_c char(30));   
  4. create index inx_col12A on a(col1,col2); 

執(zhí)行Oracle優(yōu)化查詢:

  1. select A.col4   
  2. from B, A, C   
  3. where B.col3 = 10   
  4. and A.col1 = B.col1   
  5. and A.col2 = C.col2   
  6. and C.col3 = 5;   
  7. Execution Plan   
  8. SELECT STATEMENT Optimizer=RULE   
  9. 0  MERGE JOIN   
  10. 1 SORT (JOIN)   
  11. 2  NESTED LOOPS   
  12. 3 TABLE ACCESS (FULL) OF 'B'   
  13. 3 TABLE ACCESS (BY INDEX ROWID) OF 'A'   
  14. INDEX (RANGE SCAN) OF 'INX_COL12A' (NON-UNIQUE)   
  15. 1 SORT (JOIN)   
  16. 7  TABLE ACCESS (FULL) OF 'C'  
  17. select A.col4   
  18. from B, A, C   
  19. where A.col1 = B.col1   
  20. and A.col2 = C.col2;   
  21. Execution Plan   
  22. SELECT STATEMENT Optimizer=RULE   
  23. 0  MERGE JOIN   
  24. 1 SORT (JOIN)   
  25. 2  NESTED LOOPS   
  26. 3 TABLE ACCESS (FULL) OF 'B'   
  27. 3 TABLE ACCESS (BY INDEX ROWID) OF 'A'   
  28. 5  INDEX (RANGE SCAN) OF 'INX_COL12A' (NON-UNIQUE)   
  29. 1 SORT (JOIN)   
  30. 7  TABLE ACCESS (FULL) OF 'C'  

 

將A表上的索引inx_col12A刪除后:

  1. select A.col4   
  2. from B, A, C   
  3. where A.col1 = B.col1   
  4. and A.col2 = C.col2;   
  5. Execution Plan   
  6. SELECT STATEMENT Optimizer=RULE   
  7. MERGE JOIN   
  8. 1 SORT (JOIN)   
  9. 2  MERGE JOIN   
  10. 3 SORT (JOIN)   
  11. 4  TABLE ACCESS (FULL) OF 'C'   
  12. 3 SORT (JOIN)   
  13. 6  TABLE ACCESS (FULL) OF 'A'   
  14. 1 SORT (JOIN)   
  15. 8  TABLE ACCESS (FULL) OF 'B' 

通過上面的這些例子,使我對(duì)Oracle文檔上的” All things being equal RBO chooses the driving order by taking the tables in the FROM clause RIGHT to LEFT”這句話持懷疑態(tài)度。此時(shí),我也不能使用hints來強(qiáng)制優(yōu)化器使用nested loop,如果使用了hints,這樣就自動(dòng)使用CBO優(yōu)化器,而不是RBO優(yōu)化器了。

【編輯推薦】

  1. Oracle數(shù)據(jù)庫的統(tǒng)計(jì)數(shù)據(jù)與其生成的具體方式
  2. Oracle加速計(jì)劃與推出的新門戶網(wǎng)站簡介
  3. Oracle數(shù)據(jù)庫提升效率,用3PAR
  4. 支付寶如何用Oracle 11g創(chuàng)建新一代數(shù)據(jù)的分析
  5. Oracle企業(yè)的績效管理統(tǒng)升級(jí)版簡介
責(zé)任編輯:佚名 來源: 博客園
相關(guān)推薦

2010-04-20 09:06:25

Oracle優(yōu)化

2010-04-27 09:38:57

Oracle修改表ow

2010-05-12 10:17:59

MySQL數(shù)據(jù)庫優(yōu)化

2010-05-10 18:38:08

Oracle分頁語句

2017-08-07 15:52:33

Oracleonnect by優(yōu)化

2010-04-13 15:04:16

Oracle優(yōu)化

2010-11-18 13:32:12

Oracle分頁查詢

2011-09-08 16:30:59

SQL Server查詢

2010-10-27 10:11:07

Oracle分頁查詢

2009-04-09 13:14:09

Oracle分頁查詢CBO

2010-05-04 15:15:39

Oracle分頁查詢

2010-10-27 15:34:37

oracle查詢

2009-01-04 17:41:07

2011-08-11 17:17:56

Java

2009-03-04 09:06:56

優(yōu)化sqlOracle

2010-04-02 10:04:21

Oracle結(jié)構(gòu)

2010-04-20 15:58:15

Oracle 語句

2010-05-07 11:00:25

Oracle多表查詢

2010-04-12 17:47:01

Oracle多表查詢

2010-04-27 10:32:54

Oracle優(yōu)化CPU
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)