在Oracle中解释计划 - 如何检测最有效的查询?

时间:2018-01-16 15:15:55

标签: oracle explain

简介

我正在编写一个查询来比较包含哈希的2个不同的oracle数据库表。

我想找到位置1中的哪些哈希值,但尚未迁移到位置2。

我有三个不同的查询,并为它们编写了explain plan for个语句。

然而,结果并没有告诉我那么多。

问题

如何找到效率最高,速度最快的?

当前猜测

但我怀疑第一个查询是最快的,因为它一次性使用远程链接。但这只是一个实际结果不支持的猜测。

代码

--------------------------

EXPLAIN PLAN
SET statement_id = 'ex_plan1' FOR
select* from document doc left outer join migrated_document@V2_PROD migrated on doc.hash = migrated.document_hash AND migrated.document_hash is null ;

SELECT PLAN_TABLE_OUTPUT
FROM TABLE(DBMS_XPLAN.DISPLAY(NULL, 'ex_plan1','BASIC'));

---------------------------------------------------
| Id  | Operation             | Name              |
---------------------------------------------------
|   0 | SELECT STATEMENT      |                   |
|   1 |  HASH JOIN RIGHT OUTER|                   |
|   2 |   REMOTE              | MIGRATED_DOCUMENT |
|   3 |   TABLE ACCESS FULL   | DOCUMENT          |
---------------------------------------------------


--------------------------

EXPLAIN PLAN
SET statement_id = 'ex_plan2' FOR
select* from document doc where not exists( select 1 from migrated_document@V2_PROD migrated where migrated.document_hash = doc.HASH ) ;

SELECT PLAN_TABLE_OUTPUT
FROM TABLE(DBMS_XPLAN.DISPLAY(NULL, 'ex_plan2','BASIC'));

------------------------------------------------
| Id  | Operation          | Name              |
------------------------------------------------
|   0 | SELECT STATEMENT   |                   |
|   1 |  FILTER            |                   |
|   2 |   TABLE ACCESS FULL| DOCUMENT          |
|   3 |   REMOTE           | MIGRATED_DOCUMENT |
------------------------------------------------


--------------------------

EXPLAIN PLAN
SET statement_id = 'ex_plan3' FOR
select* from document doc where doc.hash not in ( select migrated.document_hash from migrated_document@V2_PROD migrated) ;

SELECT PLAN_TABLE_OUTPUT
FROM TABLE(DBMS_XPLAN.DISPLAY(NULL, 'ex_plan3','BASIC'));

------------------------------------------------
| Id  | Operation          | Name              |
------------------------------------------------
|   0 | SELECT STATEMENT   |                   |
|   1 |  NESTED LOOPS ANTI |                   |
|   2 |   TABLE ACCESS FULL| DOCUMENT          |
|   3 |   REMOTE           | MIGRATED_DOCUMENT |
------------------------------------------------


--------------------------

更新

我更新了explain plan语句以获得更多结果。 由于远程操作...可能会花费更少但速度更慢?

如果我正确地读取数据,似乎选项2是最好的。 但我仍然认为选项1更快。

-------------------------------------------------------------------------------------------
| Id  | Operation             | Name              | Rows  | Bytes | Cost  | Inst   |IN-OUT|
-------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |                   |   105K|    51M|   194 |        |      |
|   1 |  HASH JOIN RIGHT OUTER|                   |   105K|    51M|   194 |        |      |
|   2 |   REMOTE              | MIGRATED_DOCUMENT |     1 |   275 |     2 | V2_MN~ | R->S |
|   3 |   TABLE ACCESS FULL   | DOCUMENT          |   105K|    23M|   192 |        |      |
-------------------------------------------------------------------------------------------


----------------------------------------------------------------------------------------
| Id  | Operation          | Name              | Rows  | Bytes | Cost  | Inst   |IN-OUT|
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |                   |   105K|    23M|   104K|        |      |
|   1 |  FILTER            |                   |       |       |       |        |      |
|   2 |   TABLE ACCESS FULL| DOCUMENT          |   105K|    23M|   192 |        |      |
|   3 |   REMOTE           | MIGRATED_DOCUMENT |     1 |    50 |     1 | V2_MN~ | R->S |
----------------------------------------------------------------------------------------


----------------------------------------------------------------------------------------
| Id  | Operation          | Name              | Rows  | Bytes | Cost  | Inst   |IN-OUT|
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |                   |   105K|    29M|   526 |        |      |
|   1 |  NESTED LOOPS ANTI |                   |   105K|    29M|   526 |        |      |
|   2 |   TABLE ACCESS FULL| DOCUMENT          |   105K|    23M|   192 |        |      |
|   3 |   REMOTE           | MIGRATED_DOCUMENT |     1 |    50 |     0 | V2_MN~ | R->S |
----------------------------------------------------------------------------------------

1 个答案:

答案 0 :(得分:1)

在完美的世界中,您会选择成本最低的计划。但是,我不认为您的第一个查询符合您的要求。它看起来像没有行会加入;你应该使用过滤谓词而不是连接。

而不是

select * from document doc 
left outer join migrated_document@V2_PROD migrated 
  on doc.hash = migrated.document_hash 
AND migrated.document_hash is null

应该是

select * from document doc 
left outer join migrated_document@V2_PROD migrated 
  on doc.hash = migrated.document_hash 
WHERE migrated.document_hash is null