解释计划和查询执行时间差异

时间:2014-08-20 18:13:18

标签: sql oracle oracle10g sql-execution-plan

我有两个表TABLE_ATABLE_B(一对多。表b中的table_a的FK)。我已经编写了以下3个查询,每个查询将以不同的速度在表上执行,但基本上它们都在做同样的事情。

时间: 3.916秒。

SELECT count(*)
FROM TABLE_A hconn
WHERE EXISTS
  (SELECT *
  FROM TABLE_B hipconn
  WHERE HIPCONN.A_ID = HCONN.A_ID
  );

时间:3.52秒

 SELECT COUNT(*)
FROM TABLE_A hconn,
  TABLE_B HIPCONN
WHERE HCONN.A_ID = HIPCONN.A_ID;

时间:2.72秒。

 SELECT COUNT(*)
FROM TABLE_A HCONN
JOIN TABLE_B HIPCONN
ON HCONN.A_ID = HIPCONN.A_ID;

从上面的时间,我们可以知道最后一个查询比其他查询表现更好。 (我已经对它们进行了多次测试,它们都按照提到的相同顺序执行,但最后的查询总是表现良好。)

我已经开始查看上述查询的explain plan,以了解其发生的原因。

查询解释计划,它为所有上述查询打印出相同的costtime,没有任何区别。(下面解释计划)我重新运行了几次,但结果是所有上述查询都相同。

问题:当解释计划显示所有查询需要相同的时间时,为什么结果的速度会有所不同?我哪里错了?

Plan hash value: 600428245

-------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                      | Name                           | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |                                |     1 |    11 |       | 12913   (2)| 00:02:35 |
|   1 |  SORT AGGREGATE                |                                |     1 |    11 |       |            |          |
|*  2 |   HASH JOIN RIGHT SEMI         |                                |  2273K|    23M|    39M| 12913   (2)| 00:02:35 |
|   3 |    INDEX STORAGE FAST FULL SCAN| BIN$ACCkNNuTHKPgUJAKNJgj5Q==$0 |  2278K|    13M|       |  1685   (2)| 00:00:21 |
|   4 |    INDEX STORAGE FAST FULL SCAN| BIN$ACCkNNubHKPgUJAKNJgj5Q==$0 |  6448K|    30M|       |  4009   (2)| 00:00:49 |
-------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("HIPCONN"."A_ID"="HCONN"."A_ID")

1 个答案:

答案 0 :(得分:1)

您可以使用DBMS_XPLAN.DISPLAY_CURSOR显示上次执行的SQL语句的实际执行计划,因为查询可能在库缓存中有多个执行计划。

此外,您可以在级别12启用10046跟踪,以检查查询为何以不同的执行时间进行响应。