[英]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
,字段ape1
, ape2
和iden
。 所有索引都很简单。
我不明白为什么我的性能这么差... ape1
和ape2
的两个索引不足以提高连接速度吗?
先感谢您!!
编辑:我想要实现的是这样的:
让我们将正确的记录定义为内部选择中选择的记录。
我试图获取以前意义上不正确的记录,但仍然适合某些属性,这些记录是:
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语法。 它使连接错误更容易识别。
我还注意到您正在使用许多字符串数字。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.