簡體   English   中英

表聯接性能不佳

[英]Poor performance in tables join

我在Oracle SQL查詢中遇到了非常差的性能。 查詢是這樣的:

 SELECT distinct idm3.cod
    FROM ibe_partos_m idm3, ibe_padron_prov_2010_m pad2
   WHERE     idm3.codLote = 1
         AND idm3.activo = 1
         AND ((pad2.ar = '2016' and pad2.mes='1') or (pad2.ar = '2015' and pad2.mes='7'))
         AND idm3.cod NOT IN                
           (SELECT idm2.cod
              FROM ibe_partos_m idm2,
                   ibe_padron_prov_2010_m pad
             WHERE     idm2.codLote = 1
                   AND idm2.activo = 1
                   AND ((pad.ar = '2016' and pad.mes='1') or (pad.ar = '2015' and pad.mes='7'))
                   AND pad.tiden != '2'
                   AND idm2.nombreM = pad.NOMB
                   AND idm2.apell1m = pad.APE1
                   AND idm2.apell2m = pad.APE2
                   AND (    idm2.numdocm = pad.IDEN || pad.LIDEN OR 
                                idm2.numdocm = pad.NDOCU OR 
                                idm2.numdocm = pad.LEXTR|| pad.IDEN|| pad.LIDEN OR 
                                idm2.numdocm = pad.LEXTR || '0' || pad.IDEN|| pad.LIDEN OR 
                                idm2.numdocm = pad.lextr || SUBSTR (pad.iden, 2, LENGTH (pad.iden))|| pad.liden)
                )                        
         AND idm3.PROREM = '07'
         AND idm3.nombreM = pad2.nomb
         AND idm3.apell1m = pad2.ape1
         AND idm3.apell2m = pad2.ape2
         AND (   (pad2.tiden = '1' AND pad2.liden IS NOT NULL)
              OR (    pad2.tiden = '3'
                  AND pad2.liden IS NOT NULL
                  AND pad2.lextr IS NOT NULL));

我已經在表ibe_partos_m ,字段codlote和字段cod定義了索引; 在表ibe_padron_prov_2010_m ,字段ape1ape2iden 所有索引都很簡單。

我不明白為什么我的性能這么差... ape1ape2的兩個索引不足以提高連接速度嗎?

先感謝您!!

編輯:我想要實現的是這樣的:

  • 讓我們將正確的記錄定義為內部選擇中選擇的記錄。

  • 我試圖獲取以前意義上不正確的記錄,但仍然適合某些屬性,這些記錄是:

     idm3.codLote = 1 AND idm3.activo = 1 AND ((pad2.ar = '2016' and pad2.mes='1') or (pad2.ar = '2015' and pad2.mes='7')) AND idm3.PROREM = '07' AND idm3.nombreM = pad2.nomb AND idm3.apell1m = pad2.ape1 AND idm3.apell2m = pad2.ape2 AND ( (pad2.tiden = '1' AND pad2.liden IS NOT NULL) OR ( pad2.tiden = '3' AND pad2.liden IS NOT NULL AND pad2.lextr IS NOT NULL)); 

Edit2:正如@Craig Young正確懷疑的那樣,我只對(在兩個選擇中)都感興趣,以獲取獨特的cod ……但是有某種方法可以告訴DB服務器一旦在某些地方找到匹配項就停止搜索給定的ibe_partos_m 。還是兩者都選?

使用JOIN使代碼更易於閱讀,因為它是不言自明的。

保證LEFT JOIN返回idm2的每一行

並且adm2.cod為null;

select distinct idm3.cod
  from ibe_partos_m idm3

  inner join ibe_padron_prov_2010_m pad2
     on idm3.nombrem = pad2.nomb
     and idm3.apell1m = pad2.ape1
     and idm3.apell2m = pad2.ape2

  left join (select idm2.cod
          from ibe_partos_m idm2
          inner join ibe_padron_prov_2010_m pad
           on idm2.nombrem = pad.nomb
           and idm2.apell1m = pad.ape1
           and idm2.apell2m = pad.ape2  
         where idm2.codlote = 1
           and idm2.activo = 1
           and ((pad.ar = '2016' and pad.mes = '1') or
               (pad.ar = '2015' and pad.mes = '7'))
           and pad.tiden != '2'         
           and (idm2.numdocm = pad.iden || pad.liden or
               idm2.numdocm = pad.ndocu or
               idm2.numdocm = pad.lextr || pad.iden || pad.liden or
               idm2.numdocm = pad.lextr || '0' || pad.iden || pad.liden or
               idm2.numdocm =
               pad.lextr || substr(pad.iden, 2, length(pad.iden)) ||
               pad.liden))  idm2
   on idm3.cod = idm2.cod   

 where idm3.codlote = 1
   and idm3.activo = 1
   and ((pad2.ar = '2016' and pad2.mes = '1') or
       (pad2.ar = '2015' and pad2.mes = '7'))
   and idm3.prorem = '07'
   and ((pad2.tiden = '1' and pad2.liden is not null) or
       (pad2.tiden = '3' and pad2.liden is not null and
       pad2.lextr is not null))
    and adm2.cod is null;

警鍾在以下地點尖叫:

SELECT distinct idm3.cod

由於查詢中的連接錯誤,您可能正在使用DISTINCT隱藏重復項。 如果將其更改為以下內容,您可能會看到您正在生成大量行,只是為了散出重復項:

SELECT COUNT(idm3.cod)

我們不知道您的架構,因此我們無法指出您的錯誤。 但是您可以通過檢查每個表的PK字段的適當過濾開始。

我還建議遵循Leketo的建議,並使用顯式的JOIN語法。 它使連接錯誤更容易識別。


我還注意到您正在使用許多字符串數字。

  • 如果基礎字段是char / varchar:您的表設計效率低下。 通過將這些列更改為適當的數字類型,可以顯着改善此功能。
  • 如果基礎字段已經是數字類型:使用字符串字面量過濾器可能會導致不可持久查詢(即,您無法利用索引)。 開始使用正確的類型,您可能會看到明顯的改進。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM