­

SELECT和DELETE執行計劃的不同選擇

  • 2019 年 10 月 27 日
  • 筆記

版權聲明:本文為博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。

本文鏈接:https://blog.csdn.net/bisal/article/details/102735217

模擬表名,A表的數據量約1000萬,B表的數據量約500萬,進行連接,其中這幾個條件字段,都創建了索引,

SQL> SELECT * from A a inner join B b on a.ID = b.id       where b.C_DATE <= trunc(sysdate)-1000;

我們知道在CBO優化器模式下,Oralce會基於Cost成本,來選擇執行計劃。從執行計劃看,全表掃描用的Hash Join,被驅動表只掃描一次,HINT使用索引則用的嵌套循環連接Nested Loop,兩個表的記錄都很多,哪個表做被驅動表都會導致掃描次數過多,回表也過多,而且索引的CF高,索引掃描的成本,會更高些,SELECT返回所有列,需要考慮回表,因此乾脆不回表,選擇全表掃描,從Cost能看出,HINT索引的值更高。

從10053能看到SELECT的執行計劃成本計算,根本沒考慮索引,鑒於SELECT *和較高的CF,能不回表就不回表了,

PLAN_TABLE_OUTPUT  ------------------------------------------------------------------------------------------------    ------------------------------------------------------------------------------------------------  | Id  | Operation                      | Name          | Rows  | Bytes | Cost (%CPU)| Time     |  ------------------------------------------------------------------------------------------------  |   0 | DELETE STATEMENT               |               | 10000 |   195K|  5040   (1)| 00:01:01 |  |   1 |  DELETE                        | A             |       |       |            |          |  |*  2 |   COUNT STOPKEY                |               |       |       |            |          |  |   3 |    NESTED LOOPS                |               | 85666 |  1673K|  5040   (1)| 00:01:01 |  |   4 |     TABLE ACCESS BY INDEX ROWID| B             | 85666 |  1171K|  5034   (1)| 00:01:01 |  |*  5 |      INDEX RANGE SCAN          | IDX_B_01      | 85666 |       |   232   (1)| 00:00:03 |  |*  6 |     INDEX UNIQUE SCAN          | PK_A_ID       |     1 |     6 |     0   (0)| 00:00:01 |  ------------------------------------------------------------------------------------------------    Predicate Information (identified by operation id):  ---------------------------------------------------       2 - filter(ROWNUM<=10000)     5 - access("B"."C_DATE"<=TRUNC(SYSDATE@!)-1000)     6 - access("A"."ID"="B"."ID")

DELETE的時候,畢竟要刪除數據,因此回表勢在必行的,只能在回表的各種路徑中找一個合適的,所以會考慮索引路徑,

SELECT和DELETE即使條件相同,相應的執行計劃,可能還是有差別,歸根結底在於Cost的計算和判斷,如上例所示,可能會考慮是否需要回表、CF值高低等因素,所以Oracle在這方面還是很智能的,優化器的算法,作為他的核心商業機密,也就不足為奇了。