两个相似的表,但联接性能不同

时间:2019-06-14 23:28:12

标签: sql oracle oracle11g database-performance

我正在使用两个不同的表运行完全相同的联接查询,但是第一个(表A)超时,而第二个(表B)超时。

SELECT * FROM table_X
INNER JOIN table_A
ON table_A.point_origin = table_X.item_id
WHERE ROWNUM < 10;

SELECT * FROM table_X
INNER JOIN table_B
ON table_B.point_origin = table_X.item_id
WHERE ROWNUM < 10;

据我所知,表A是表B的子集。表A和表B都没有point_origin索引。

(为澄清起见,就行标识符而言,表A仅是表B的子集,而不是确切的列数据。)

对于它的价值,我正在处理非常大的表,并且对item_id进行了索引。

还有其他会影响性能的信息吗?或者我对所提供的某些信息肯定错了吗?

编辑:下面每条评论的其他信息

table_A:

---------------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name                | Rows  | Bytes | Cost (%CPU)| Pstart| Pstop |
---------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                     |     9 |  4743 |    12   (0)|       |       |
|*  1 |  COUNT STOPKEY               |                     |       |       |            |       |       |
|   2 |   TABLE ACCESS BY INDEX ROWID| table_X             |     1 |   227 |     1   (0)|       |       |
|   3 |    NESTED LOOPS              |                     |    11 |  5797 |    12   (0)|       |       |
|   4 |     PARTITION RANGE ALL      |                     |    10M|  2969M|     2   (0)|     1 |     4 |
|   5 |      TABLE ACCESS FULL       | table_A             |    10M|  2969M|     2   (0)|     1 |     4 |
|*  6 |     INDEX RANGE SCAN         | table_X_IP_PK       |     1 |       |     1   (0)|       |       |
---------------------------------------------------------------------------------------------------------

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

   1 - filter(ROWNUM<10)
   6 - access("table_A"."POINT_ORIGIN"="table_X"."ITEM_ID")

Note
-----
   - 'PLAN_TABLE' is old version

table_B:

-----------------------------------------------------------------------------------------
| Id  | Operation                    | Name                | Rows  | Bytes | Cost (%CPU)|
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                     |     9 |  3879 |    11   (0)|
|*  1 |  COUNT STOPKEY               |                     |       |       |            |
|   2 |   TABLE ACCESS BY INDEX ROWID| table_X             |     1 |   227 |     1   (0)|
|   3 |    NESTED LOOPS              |                     |    10 |  4310 |    11   (0)|
|   4 |     TABLE ACCESS FULL        | table_B             |   118M|    22G|     2   (0)|
|*  5 |     INDEX RANGE SCAN         | table_X_IP_PK       |     1 |       |     1   (0)|
-----------------------------------------------------------------------------------------

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

   1 - filter(ROWNUM<10)
   5 - access("table_B"."POINT_ORIGIN"="table_X"."ITEM_ID")

Note
-----
   - 'PLAN_TABLE' is old version

1 个答案:

答案 0 :(得分:0)

似乎table_a已分区,并且查询table_b未分区时只需要扫描4个分区,因此必须完整读取。优化器估计table_a的4个分区有1000万行,而table_b的分区有1.18亿行。您使用的是嵌套循环,因此希望获得O(n)性能,因此根据统计信息,第二个查询所花的时间是第一个查询的〜11.8倍。

优化器的估算值是否准确?该优化器的性能仅与您提供的统计信息一样好,并且一个或两个表都有过时的统计信息。