2013-10-31 73 views
1
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 
+1

什麼是列定義?其中一列是否允許NULLS?你可以發佈計劃嗎? – SriniV

+4

這聽起來像主鍵被聲明爲'(b_item_id,a_item_id)'。添加一個輔助索引作爲'(a_item_id,b_item_id)',這應該有助於你的查詢。 –

+0

嗨realspirituals,這兩列都有NOT NULL約束。 – user2767714

回答

0

它不會因爲使用複合索引需要使用「左」的所有鍵。如果索引位於字段(A,B,C)上,並且您的條件位於B和C上,那麼該索引對於您的查詢來說沒有用處。因此,從(a_item_id,b_item_id)和(b_item_id,a_item_id)中選擇哪一個最適合您如何使用表格。

+0

事實上,即使第一個索引列不在條件中,Oracle實際上也可以使用索引,但它不能使用範圍掃描來遍歷索引。同樣,如果這樣一個索引的大小與表大小相似,那麼CBO將直接使用該表(或者它將使用其他索引)。 – ibre5041

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)