Oracle查询调优

时间:2011-09-15 23:28:42

标签: sql performance oracle

有谁知道为什么在我拥有的这3个查询中,最快的是使用where not exists的那个?

这篇文章Rewrite SQL Subqueries as Outer Joins表示您可以将where not exists更改为正常join。我误会了吗?有人可以解释这个区别吗?

这个在.73秒内完成所有3293行

SELECT *
FROM
(SELECT TRIM(TO_CHAR(C21.PINO,'999999999999999')) DN,
C21.INVD,
TRIM(TO_CHAR(C21.ORNO,'999999999999999')),
C21.CFRW,
C21.LIFEX,
C22.PONO,
C22.ITEM,
C22.OQUA,
C71.REFA,
C71.CDEC,
C81.COPO,
DECODE(SUBSTR(TRIM(C22.ITEM),1,3), 'PRD', 1, 'ASY', 2, 'SLA', 3),
C84.NAMA,
C84.CCTY
FROM CMS.CMPPS021@RO_CMS_PRD C21,
CMS.CMPPS022@RO_CMS_PRD C22,
CMS.CMPPS071@RO_CMS_PRD C71,
CMS.CMPPS081@RO_CMS_PRD C81,
CMS.CMPPS084@RO_CMS_PRD C84
WHERE C21.PINO = C22.PINO
AND DECODE( SUBSTR(TRIM(C22.ITEM),1,3) , 'PRD', 'Y', 'ASY', 'Y', 'SLA', 'Y', 'N' ) = 'Y'
AND C21.ORNO = C71.ORNO
AND C21.ORNO = C81.ORNO
AND C22.PONO = C81.PONO
AND C21.ORNO = C84.ORNO
AND C84.CTYP = 'ST'
AND C21.NCMP = 'F555'
AND C21.INVD >= TO_DATE('01012011','MMDDYYYY')
ORDER BY C21.PINO,
C22.PONO
) T1
WHERE NOT EXISTS
( SELECT 1 FROM SHIPPINGCONTROL S WHERE T1.DN=S.S_DN
) ; 

这个在2秒内完成

SELECT TRIM(TO_CHAR(C21.PINO,'999999999999999')) DN,
C21.INVD,
TRIM(TO_CHAR(C21.ORNO,'999999999999999')),
C21.CFRW,
C21.LIFEX,
C22.PONO,
C22.ITEM,
C22.OQUA,
C71.REFA,
C71.CDEC,
C81.COPO,
DECODE(SUBSTR(TRIM(C22.ITEM),1,3),'PRD',1,'ASY',2,'SLA',3),
C84.NAMA,
C84.CCTY
FROM CMS.CMPPS021@RO_CMS_PRD C21,
CMS.CMPPS022@RO_CMS_PRD C22,
CMS.CMPPS071@RO_CMS_PRD C71,
CMS.CMPPS081@RO_CMS_PRD C81,
CMS.CMPPS084@RO_CMS_PRD C84,
(SELECT C21.PINO DN
FROM CMS.CMPPS021@RO_CMS_PRD C21
WHERE C21.INVD>=TO_DATE('01012011','MMDDYYYY')
AND C21.NCMP     ='F555'
MINUS
SELECT TO_NUMBER(G_DN) FROM GENERALINFO
) DNSTOFIND
WHERE C21.PINO =C22.PINO
AND DECODE(SUBSTR(TRIM(C22.ITEM),1,3),'PRD','Y','ASY','Y','SLA','Y','N')='Y'
AND C21.ORNO =C71.ORNO
AND C21.ORNO =C81.ORNO
AND C22.PONO =C81.PONO
AND C21.ORNO =C84.ORNO
AND C84.CTYP ='ST'
AND DNSTOFIND.DN =C21.PINO
ORDER BY C21.PINO,
C22.PONO;

这个在4秒内完成

SELECT TRIM(TO_CHAR(C21.PINO,'999999999999999')) DN,
C21.INVD,
TRIM(TO_CHAR(C21.ORNO,'999999999999999')),
C21.CFRW,
C21.LIFEX,
C22.PONO,
C22.ITEM,
C22.OQUA,
C71.REFA,
C71.CDEC,
C81.COPO,
DECODE(SUBSTR(TRIM(C22.ITEM),1,3),'PRD',1,'ASY',2,'SLA',3),
C84.NAMA,
C84.CCTY
FROM CMS.CMPPS021@RO_CMS_PRD C21,
CMS.CMPPS022@RO_CMS_PRD C22,
CMS.CMPPS071@RO_CMS_PRD C71,
CMS.CMPPS081@RO_CMS_PRD C81,
CMS.CMPPS084@RO_CMS_PRD C84,
(SELECT C21.PINO DN
FROM CMS.CMPPS021@RO_CMS_PRD C21,
    GENERALINFO G
WHERE C21.INVD>=TO_DATE('01012011','MMDDYYYY')
AND C21.NCMP     ='F555'
AND C21.PINO     =G.G_DN(+)
AND G.G_DN        IS NULL
) DNSTOFIND
WHERE C21.PINO =C22.PINO
AND DECODE(SUBSTR(TRIM(C22.ITEM),1,3),'PRD','Y','ASY','Y','SLA','Y','N')='Y'
AND C21.ORNO =C71.ORNO
AND C21.ORNO =C81.ORNO
AND C22.PONO =C81.PONO
AND C21.ORNO =C84.ORNO
AND C84.CTYP ='ST'
AND DNSTOFIND.DN =C21.PINO
ORDER BY C21.PINO,
C22.PONO;

2 个答案:

答案 0 :(得分:1)

我注意到你在where子句上进行了很多基于函数的计算,在使用函数的情况下列索引被压缩,除非函数是基于索引的,

答案 1 :(得分:0)

  

“有谁知道为什么这三个我有的查询最快   一个是使用不存在的那个?“

它是唯一一个引用SHIPPINGCONTROL表的,因此它是一个不同的查询。人们会期望不同的查询具有不同的执行计划,因此具有不同的检索时间。