2011-09-15 49 views
-2

有沒有人知道爲什麼,我有這3個查詢,最快的是使用where not existsOracle查詢調整

這篇文章Rewrite SQL Subqueries as Outer Joins說,你可以將where not exists更改爲正常join。我誤解了嗎?有人可以解釋這種差異嗎?

這一個做它在0.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 [email protected]_CMS_PRD C21, 
[email protected]_CMS_PRD C22, 
[email protected]_CMS_PRD C71, 
[email protected]_CMS_PRD C81, 
[email protected]_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 [email protected]_CMS_PRD C21, 
[email protected]_CMS_PRD C22, 
[email protected]_CMS_PRD C71, 
[email protected]_CMS_PRD C81, 
[email protected]_CMS_PRD C84, 
(SELECT C21.PINO DN 
FROM [email protected]_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 [email protected]_CMS_PRD C21, 
[email protected]_CMS_PRD C22, 
[email protected]_CMS_PRD C71, 
[email protected]_CMS_PRD C81, 
[email protected]_CMS_PRD C84, 
(SELECT C21.PINO DN 
FROM [email protected]_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

歡迎來到StackOverflow。我希望你的真實SQL不會像你發佈的那樣間隔太大和格式不對。我做了一些編輯讓你開始,但大約10分鐘後試圖修復它,但放棄了。請編輯您的帖子,以在「C1 = C2,C3,C4」(注意它們所屬的空間)等條件之間提供適當的間距,以便線條正確折斷,然後將它們分開,以使其長度可讀。您可以通過在頁面中向下滾動來預覽帖子;預覽位於代碼編輯窗口下方。原來,你的帖子是不可讀的,可能無法獲得答案。 :) –

+0

此外,在您的問題標題中的SHOUTING無法幫助您更快地獲得答案。 :)它只是讓閱讀變得更加困難。 –

+0

對不起,這是更好嗎?還有你的意思是喊什麼?它只是說Oracle Query Tuning或者它應該是其他方式? – Mario

回答

1

我注意到你在where子句中做了很多基於函數的計算,列索引超出了d,其中功能被使用,除非該功能是基於指數,

+0

是的,但它們與3個查詢中使用的一樣,這就是爲什麼我沒有得到它的錯誤 – Mario

0

「有誰知道這是爲什麼,這3個querys我有,最快 一個是使用其中不存在嗎?」

這是唯一一個引用SHIPPINGCONTROL表的,因此它是一個不同的查詢。人們會期望不同的查詢具有不同的執行計劃並因此具有不同的檢索時間。

+0

是這是真的,但我忘了提及航運控制基本上有相同的記錄和指數GENERALINFO – Mario

+0

@Mario - 抱歉,你究竟是什麼期望我們告訴你?您可以發佈三個複雜的查詢,而不需要對任何底層業務邏輯或任何有用的上下文信息(如數據量,分佈和歪斜,索引等)的解釋。沒有解釋計劃,什麼也沒有。那麼我們應該如何解釋性能差異。 – APC

+0

咋說那是真的,下次我會盡量放好信息,現在我會用最快的查詢 – Mario