复合主键是否明确要求索引

时间:2013-10-31 12:58:38

标签: sql oracle oracle10g plsqldeveloper

select a_item_id, b_item_id from test_admin;

上面选择的列是复合主键。在where条件中使用b_item_id列时,查询执行速度更快。 如果我在where条件中使用a_item_id,则查询执行速度非常慢。

是否需要为复合主键的两列显式创建索引。

explain plan for 
SELECT A.b_item_id 
FROM child_a A,child_b B,child_c C,child_d D,child_e E
WHERE D.CDE = 1
  AND E.SUR_ID = '032'
  AND A.b_item_id = E.S_ID
  AND D.AD_ID = C.AD_ID
  AND B.PRO_ID = C.PRO_ID
  AND A.b_item_id= B.S_ID;

select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------

------------------------------------------------------------------------------------------
| Id  | Operation                     | Name        | Rows  | Bytes |TempSpc| Cost (%CPU)|
------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |             |   848 | 74624 |       |  7553   (2)|
|   1 |  HASH UNIQUE                  |             |   848 | 74624 |       |  7553   (2)|
|*  2 |   HASH JOIN                   |             | 12476 |  1072K|       |  7552   (2)|
|   3 |    TABLE ACCESS BY INDEX ROWID| CHILD_E     |   678 | 11526 |       |   148   (0)|
|*  4 |     INDEX RANGE SCAN          | CHILD_E_IN5 |   678 |       |       |     4   (0)|
|*  5 |    HASH JOIN                  |             | 15613 |  1082K|  1360K|  7403   (2)|
|*  6 |     HASH JOIN                 |             | 21679 |  1100K|       |  3864   (2)|
|*  7 |      HASH JOIN                |             | 21679 |   571K|       |  1830   (2)|
|   8 |       TABLE ACCESS FULL       | CHILD_A     | 21541 |   168K|       |    21   (0)|
|   9 |       TABLE ACCESS FULL       | CHILD_B     |  1832K|    33M|       |  1799   (2)|
|  10 |      TABLE ACCESS FULL        | CHILD_C     |  1700K|    40M|       |  2024   (1)|
|* 11 |     TABLE ACCESS FULL         | CHILD_D     |  1224K|    22M|       |  1665   (2)|
------------------------------------------------------------------------------------------

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

2 - access("A"."b_item_id"="E"."S_ID")
4 - access("E"."SUR_ID"='032')
5 - access("D"."AD_ID"="C"."AD_ID")
6 - access("B"."PRO_ID"="C"."PRO_ID")
7 - access("A"."b_item_id"="B"."S_ID")
11 - filter("D"."CDE"=1) 

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

 31 rows selected

Elapsed: 00:00:01.513

2 个答案:

答案 0 :(得分:0)

它不会因为使用复合索引而需要使用“left”中的所有键。如果索引在字段(A,B,C)上,并且您的条件在B和C上,则该索引对该查询没用。因此,从(a_item_id,b_item_id)和(b_item_id,a_item_id)中选择哪一种最适合您使用该表的方式。

答案 1 :(得分:0)

如果现有索引中包含(b_item_id,a_item_id),则有助于在b_item_id或b_item_id和a_item_id上使用谓词进行查询。

要仅在a_item_id上支持带谓词的查询,请仅在该列上添加索引 - 可以使用b_item_id和a_item_id上的索引进行查询。

所以你的两个索引会打开(b_item_id,a_item_id)和(a_item_id)