2014-01-10 33 views
0

下面是該查詢如何與執行計劃和SQL查詢

UPDATE hrs.rns_recon_ho c SET c.refr_numb = 
(
SELECT seqn_numb FROM hrs.rns_recon_ho p WHERE p.narr_1 = c.narr_1 
AND p.seqn_numb = p.refr_numb AND p.prod_code = 0 
) 
Where c.prod_code = 0 And c.refr_numb = 0 
AND c.narr_1 = '3/13/201211013198693442091' 

,這裏是它的執行計劃

enter image description here 哪個查詢的一部分引起TABLE ACCESS(FULL)

編輯

我的錯,我應該更清晰。現在讓我明確自己,我需要知道如何將部分執行計劃與部分查詢關聯起來。例如

  1. 哪個查詢的一部分,是造成TABLE ACCESS(FULL)
  2. 哪個查詢的一部分,是造成TABLE ACCESS(BY GLOBAL INDEX ROWID)

但是,很顯然,INDEX(...)...PROD_CODE由PROD_CODE場引起的。

是否有任何經驗法則,準則或只是技巧來識別?或者,我們無法知道,因爲優化器不會告訴我們爲什麼選擇了某條路徑。

+0

什麼是您的主鍵?你有什麼指數?你有分區嗎? – SriniV

+0

@realspirituals'seqn_numb'是PK,所有查詢的字段都被索引,並且表被分區。 – bjan

+0

您可以發佈您的創建表,索引腳本嗎?或者在sqlfiddle.com中設置它 – SriniV

回答

0

可能強制在一張桌子上通過提示進行全表掃描,例如,

UPDATE hrs.rns_recon_ho c SET c.refr_numb = 
(
SELECT /*+ FULL(p) */ seqn_numb FROM hrs.rns_recon_ho p WHERE p.narr_1 = c.narr_1 
AND p.seqn_numb = p.refr_numb AND p.prod_code = 0 
) 
Where c.prod_code = 0 And c.refr_numb = 0 
AND c.narr_1 = '3/13/201211013198693442091' 

UPDATE /*+ FULL(c) */ hrs.rns_recon_ho c SET c.refr_numb = 
(
SELECT seqn_numb FROM hrs.rns_recon_ho p WHERE p.narr_1 = c.narr_1 
AND p.seqn_numb = p.refr_numb AND p.prod_code = 0 
) 
Where c.prod_code = 0 And c.refr_numb = 0 
AND c.narr_1 = '3/13/201211013198693442091' 

如果你的執行計劃顯示了兩個「全掃描」你知道它最初是由另外一個引起的。

+0

在這兩種情況下,只有一個完整的掃描正在顯示 – bjan

+0

也通過這個'UPDATE/* + FULL(c)FULL(p)*/hrs.rns_recon_ho c SET c.refr_numb ='? –

+0

現在有兩個完整的掃描提示是內部查詢。這是否表示外部查詢正在導致「FULL」掃描? – bjan

0

讓我重新:

CREATE TABLE RNS_RECON_HO (PROD_CODE NUMBER, 
      REFR_NUMB NUMBER, 
      NARR_1 VARCHAR2 (25), 
      SEQN_NUMB NUMBER primary key ); 

CREATE INDEX TESTTT ON RNS_RECON_HO (PROD_CODE); 
CREATE INDEX TESTTT1 ON RNS_RECON_HO (REFR_NUMB); 
CREATE INDEX TESTTT2 ON RNS_RECON_HO (NARR_1); 

現在複製你的計劃:

SET AUTOTRACE ON 

UPDATE 
     RNS_RECON_HO C 
SET 
     C.REFR_NUMB = 
      (SELECT 
       SEQN_NUMB 
      FROM 
       RNS_RECON_HO P 
      WHERE 
        P.NARR_1 = C.NARR_1 
       AND P.SEQN_NUMB = P.REFR_NUMB 
       AND P.PROD_CODE = PROD_CODE) 
WHERE 
     C.PROD_CODE = 0 
     AND C.REFR_NUMB = 0 
     AND C.NARR_1 = '3/13/201211013198693442091'; 


0 rows updated. 

Execution Plan 
---------------------------------------------------------- 
    0  UPDATE STATEMENT Optimizer Mode=ALL_ROWS (Cost=2 Card=1 Bytes=78) 
    1 0 UPDATE RNS_RECON_HO 
    2 1  TABLE ACCESS FULL RNS_RECON_HO (Cost=2 Card=1 Bytes=78) 
    3 1  TABLE ACCESS BY INDEX ROWID RNS_RECON_HO (Cost=5 Card=1 Bytes=91) 
    4 3  INDEX RANGE SCAN TESTTT (Cost=1 Card=1) 

Statistics 
---------------------------------------------------------- 
     190 recursive calls 
      0 spare statistic 3 
      0 gcs messages sent 
     25 db block gets from cache 
      0 physical reads direct (lob) 
      0 queue position update 
      0 queue single row 
      0 queue ocp pages 
      0 HSC OLTP Compressed Blocks 
      0 HSC IDL Compressed Blocks 
      0 rows processed 

原因

優化只會選擇,如果它是便宜,使用索引(少讀取)比表掃描。這通常意味着WHERE子句條件需要映射到索引的前導(即最左邊)列。因此,在where子句列中添加一個索引(PROD_CODE,REFR_NUMB,NARR_1)可以避免這種情況。

爲了確認檢查這一個

CREATE INDEX TESTTT3 ON RNS_RECON_HO (PROD_CODE, REFR_NUMB, NARR_1); 

SET AUTOTRACE ON 

UPDATE 
     RNS_RECON_HO C 
SET 
     C.REFR_NUMB = 
      (SELECT 
       SEQN_NUMB 
      FROM 
       RNS_RECON_HO P 
      WHERE 
        P.NARR_1 = C.NARR_1 
       AND P.SEQN_NUMB = P.REFR_NUMB 
       AND P.PROD_CODE = PROD_CODE) 
WHERE 
     C.PROD_CODE = 0 
     AND C.REFR_NUMB = 0 
     AND C.NARR_1 = '3/13/201211013198693442091'; 

0 rows updated. 

Execution Plan 
---------------------------------------------------------- 
    0  UPDATE STATEMENT Optimizer Mode=ALL_ROWS (Cost=1 Card=1 Bytes=78) 
    1 0 UPDATE RNS_RECON_HO 
    2 1  INDEX RANGE SCAN TESTTT3 (Cost=1 Card=1 Bytes=78) 
    3 1  TABLE ACCESS BY INDEX ROWID RNS_RECON_HO (Cost=27 Card=1 Bytes=91) 
    4 3  INDEX FULL SCAN TESTTT3 (Cost=26 Card=1) 

Statistics 
---------------------------------------------------------- 
      1 recursive calls 
      0 spare statistic 3 
      0 gcs messages sent 
      0 db block gets from cache 
      0 physical reads direct (lob) 
      0 queue position update 
      0 queue single row 
      0 queue ocp pages 
      0 HSC OLTP Compressed Blocks 
      0 HSC IDL Compressed Blocks 
      0 rows processed 

但這僅僅是改變計劃,但從來沒有承諾任何性能提升,與你給有限的投入。

跟進:

外部查詢是怎麼回事FTS因爲它忽略了指數。所以,當我們放置一個組合鍵時,索引對於優化器是直接的,並且使用相同的索引。子查詢使用索引,因爲它與索引列上的外部查詢連接。

如何確定確切的計劃無法達到100%,儘管您可以通過遵循核心規則接近可能的執行計劃。

+0

請參閱我的編輯 – bjan