SELECT和DELETE执行计划的不同选择

2019-10-27 00:17:38 浏览数 (2)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

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

模拟表名,A表的数据量约1000万,B表的数据量约500万,进行连接,其中这几个条件字段,都创建了索引,

代码语言:javascript复制
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,能不回表就不回表了,

代码语言:javascript复制
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在这方面还是很智能的,优化器的算法,作为他的核心商业机密,也就不足为奇了。

0 人点赞