成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

Oracle查詢轉(zhuǎn)換之子查詢展開

概念:子查詢展開(Subquery Unnesting)是優(yōu)化器處理帶子查詢的目標(biāo)sql的一種優(yōu)化手段,它是指優(yōu)化器不再將目標(biāo)sql中子查詢當(dāng)作一個獨立的處理單元來單獨執(zhí)行,而是將該子查詢轉(zhuǎn)換為它自身和外部查詢之間等價的表連接。這種等價連接轉(zhuǎn)換要么是將子查詢展開(即將該子查詢中的表,視圖從子查詢中拿出來,然后和外部查詢中的表,視圖做表連接),要么是不拆開但是會把該子查詢轉(zhuǎn)換為一個內(nèi)嵌視圖(Inline View)然后再和外部查詢中的表,視圖做表連接。Oracle 會確保子查詢展開所對應(yīng)的等價連接轉(zhuǎn)換的正確性,即轉(zhuǎn)換后的sql和原sql在語義上一定是等價的。當(dāng)然不是所有的子查詢都能做子查詢展開,有些子查詢是不能做這種等價表連接轉(zhuǎn)換的,這種情況下oracle就不會對其做子查詢展開,也就是說此時oracle還是會將該子查詢當(dāng)作一個獨立的處理單元來單獨執(zhí)行。另外,在oracle10g以后版本中,對于那種不拆開子查詢但是會把該子查詢轉(zhuǎn)換成一個內(nèi)嵌視圖的子查詢展開,只有當(dāng)經(jīng)過子查詢展開后的等價改寫sql的成本值小于原sql的成本值時,oracle才會對原sql執(zhí)行子查詢展開

創(chuàng)新互聯(lián)主要從事做網(wǎng)站、成都網(wǎng)站設(shè)計、網(wǎng)頁設(shè)計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)南州晴隆,十余年網(wǎng)站建設(shè)經(jīng)驗,價格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):13518219792

    子查詢展開通常都會提高原sql的執(zhí)行效率,因為如果原sql不做子查詢展開,那么通常情況下該子查詢就會在其執(zhí)行計劃的最后一步才被執(zhí)行,并且會走filter類型的執(zhí)行計劃,這也就意味著對于外部查詢所在結(jié)果集的沒一條記錄,該子查詢就會被執(zhí)行多少次,這種執(zhí)行方式的執(zhí)行效率通常情況不會太高,尤其在子查詢中包含兩個或兩個以上表連接時,此時做子查詢展開后的執(zhí)行效率往往會比走filter類型的執(zhí)行計劃高很多。

    Oracle 數(shù)據(jù)庫里子查詢前where條件如果是如下這些條件之一,那么這種類型的目標(biāo)sql在滿足了一定條件后就可以做子查詢展開,

single-row,exists,not exists,in ,not in,any,all。

范例1:

SQL> set lines 200 pagesize 1000
in寫法:
SELECT t1.cust_last_name, t1.cust_id
  FROM customers t1
 WHERE t1.cust_id IN
  4         (SELECT t2.cust_id FROM sales t2 WHERE t2.amount_sold > 700)
  5  ;
Execution Plan
----------------------------------------------------------
Plan hash value: 2448612695
----------------------------------------------------------------------------------------------------------
| Id  | Operation     | Name | Rows  | Bytes |TempSpc| Cost (%CPU)| Time | Pstart| Pstop |
----------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     | |  7059 |   158K| |  1583   (1)| 00:00:20 | | |
|*  1 |  HASH JOIN SEMI      | |  7059 |   158K|  1360K|  1583   (1)| 00:00:20 | | |
|   2 |   TABLE ACCESS FULL  | CUSTOMERS | 55500 |   704K| |   405   (1)| 00:00:05 | | |
|   3 |   PARTITION RANGE ALL| |   560K|  5469K| |   526   (2)| 00:00:07 |     1 |    28 |
|*  4 |    TABLE ACCESS FULL | SALES |   560K|  5469K| |   526   (2)| 00:00:07 |     1 |    28 |
----------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
any等價寫法:
SELECT t1.cust_last_name, t1.cust_id
  FROM customers t1
 WHERE t1.cust_id = ANY
  4   (SELECT t2.cust_id FROM sales t2 WHERE t2.amount_sold > 700)
  5  ;
Execution Plan
----------------------------------------------------------
Plan hash value: 2448612695
----------------------------------------------------------------------------------------------------------
| Id  | Operation     | Name | Rows  | Bytes |TempSpc| Cost (%CPU)| Time | Pstart| Pstop |
----------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     | |  7059 |   158K| |  1583   (1)| 00:00:20 | | |
|*  1 |  HASH JOIN SEMI      | |  7059 |   158K|  1360K|  1583   (1)| 00:00:20 | | |
|   2 |   TABLE ACCESS FULL  | CUSTOMERS | 55500 |   704K| |   405   (1)| 00:00:05 | | |
|   3 |   PARTITION RANGE ALL| |   560K|  5469K| |   526   (2)| 00:00:07 |     1 |    28 |
|*  4 |    TABLE ACCESS FULL | SALES |   560K|  5469K| |   526   (2)| 00:00:07 |     1 |    28 |
----------------------------------------------------------------------------------------------------------
exists等價寫法:
SELECT t1.cust_last_name, t1.cust_id
  FROM customers t1
 WHERE t1.cust_id = ANY
  4   (SELECT t2.cust_id FROM sales t2 WHERE t2.amount_sold > 700)
  5  ;
Execution Plan
----------------------------------------------------------
Plan hash value: 2448612695
----------------------------------------------------------------------------------------------------------
| Id  | Operation     | Name | Rows  | Bytes |TempSpc| Cost (%CPU)| Time | Pstart| Pstop |
----------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     | |  7059 |   158K| |  1583   (1)| 00:00:20 | | |
|*  1 |  HASH JOIN SEMI      | |  7059 |   158K|  1360K|  1583   (1)| 00:00:20 | | |
|   2 |   TABLE ACCESS FULL  | CUSTOMERS | 55500 |   704K| |   405   (1)| 00:00:05 | | |
|   3 |   PARTITION RANGE ALL| |   560K|  5469K| |   526   (2)| 00:00:07 |     1 |    28 |
|*  4 |    TABLE ACCESS FULL | SALES |   560K|  5469K| |   526   (2)| 00:00:07 |     1 |    28 |
----------------------------------------------------------------------------------------------------------
不展開,顯然不合理,sales表要執(zhí)行很多次:
SELECT t1.cust_last_name, t1.cust_id
  FROM customers t1
 WHERE t1.cust_id IN (SELECT /*+ no_unnest */
                       t2.cust_id
                        FROM sales t2
                       WHERE t2.amount_sold > 700)

子查詢展開后,變成hash 半連接:

等價寫法:(如果cust_id是唯一鍵值)可以轉(zhuǎn)換為內(nèi)連接:

SELECT t1.cust_last_name, t1.cust_id
  FROM customers t1, sales t2
 WHERE t1.cust_id= t2.cust_id
   AND t2.amount_sold > 700

如果是not in,則會轉(zhuǎn)換為hash 反連接:

SQL> set autot trace
SELECT t1.cust_last_name, t1.cust_id
  FROM customers t1
 WHERE t1.cust_id not in 
  4   (SELECT t2.cust_id FROM sales t2 WHERE t2.amount_sold > 700);
Execution Plan
----------------------------------------------------------
Plan hash value: 2850422635
----------------------------------------------------------------------------------------------------------
| Id  | Operation     | Name | Rows  | Bytes |TempSpc| Cost (%CPU)| Time | Pstart| Pstop |
----------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     | | 48441 |  1088K| |  1583   (1)| 00:00:20 | | |
|*  1 |  HASH JOIN ANTI      | | 48441 |  1088K|  1360K|  1583   (1)| 00:00:20 | | |
|   2 |   TABLE ACCESS FULL  | CUSTOMERS | 55500 |   704K| |   405   (1)| 00:00:05 | | |
|   3 |   PARTITION RANGE ALL| |   560K|  5469K| |   526   (2)| 00:00:07 |     1 |    28 |
|*  4 |    TABLE ACCESS FULL | SALES |   560K|  5469K| |   526   (2)| 00:00:07 |     1 |    28 |
----------------------------------------------------------------------------------------------------------

把子查詢轉(zhuǎn)換成內(nèi)聯(lián)視圖:

SELECT t1.cust_last_name, t1.cust_id
  FROM customers t1
 WHERE t1.cust_id NOT IN
       (SELECT t2.cust_id
          FROM sales t2, products t3
         WHERE t2.prod_id = t3.prod_id and t2.amount_sold > 700)
Execution Plan
----------------------------------------------------------
Plan hash value: 1272298339
--------------------------------------------------------------------------------------------------------------
| Id  | Operation       | Name     | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     | Pstart| Pstop |
--------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |     | 48441 |1229K|     |1665   (1)| 00:00:20 |     |     |
|*  1 |  HASH JOIN ANTI        |     | 48441 |1229K|1360K|1665   (1)| 00:00:20 |     |     |
|   2 |   TABLE ACCESS FULL    | CUSTOMERS   | 55500 | 704K|     | 405   (1)| 00:00:05 |     |     |
|   3 |   VIEW       | VW_NSO_1    | 560K|7110K|     | 529   (2)| 00:00:07 |     |     |
|*  4 |    HASH JOIN       |     | 560K|9844K|     | 529   (2)| 00:00:07 |     |     |
|   5 |     INDEX FULL SCAN    | PRODUCTS_PK |  72 | 288 |     |   1   (0)| 00:00:01 |     |     |
|   6 |     PARTITION RANGE ALL|     | 560K|7657K|     | 526   (2)| 00:00:07 |   1 |  28 |
|*  7 |      TABLE ACCESS FULL | SALES     | 560K|7657K|     | 526   (2)| 00:00:07 |   1 |  28 |
--------------------------------------------------------------------------------------------------------------

這里oracle把子查詢轉(zhuǎn)換成內(nèi)聯(lián)視圖 VM_NSO_1,然后再和外部查詢中的表customers做hash半連接。

等價:

SELECT t1.cust_last_name, t1.cust_id
  FROM customers t1,
       (SELECT t2.cust_id
          FROM sales t2, products t3
         WHERE t2.prod_id = t3.prod_id
           AND t2.amount_sold > 700) vm_nso_1
 WHERE t1.cust_id semi = vm_nso_1.cust_id

子查詢是否能夠做子查詢展開取決于如下兩個條件:

    子查詢展開所對應(yīng)的等價改寫sql和原sql在語義上一定要完全等價的,如果改寫后的sql和原sql并不一定能保持語義上的完全等價,這種類型的子查詢就不能做子查詢展開。

    對于不能拆開的子查詢但是會把它轉(zhuǎn)換為一個內(nèi)嵌視圖的子查詢展開,只有經(jīng)過子查詢展開的等價改寫sql成本值小于原sql的成本值。oracle才會對目標(biāo)sql執(zhí)行子查詢展開。

對于子查詢展開的第一種情形(即將子查詢展開,把該子查詢中的表,視圖從子查詢中拿出來,然后和外部查詢中表,視圖做表連接),即使在oracle  10g以后的版本中,oracle也不會考慮子查詢展開的成本,即oracle此時會認(rèn)為這種情形下子查詢展開的效率始終比不展開的效率高,這就意味著如果目標(biāo)sql滿足子查詢展開的第一種情形。則oracle始終會做子查詢展開,而不管經(jīng)過子查詢展開后的等價sql的成本值是否小于原sql的成本值。

當(dāng)前標(biāo)題:Oracle查詢轉(zhuǎn)換之子查詢展開
標(biāo)題來源:http://jinyejixie.com/article32/ggiosc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站、服務(wù)器托管、全網(wǎng)營銷推廣、搜索引擎優(yōu)化、App設(shè)計、手機網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都app開發(fā)公司