基本上,你就完蛋了,因爲一個不好的設計,歡迎來到我的世界=)
無論如何,當我看着它,你只有2場,你可以用它來加入交易回其引用交易:STORE
和DATE
(儘管後者比較「粗糙」)。由於他們決定只存儲交易的最後7位數字,所以加快這一點的唯一方法是添加一個存儲這7位數字的新字段。但是,如果你走上這條路,將整個REF語法存儲在新的(計算的)字段中會更有意義。
這肯定會是最痛苦的解決了這個問題,因爲你將能夠添加一個索引在上述領域,然後改變你的查詢
SELECT *
FROM transactions t1
JOIN transactions t2
ON t2.TRAN_AS_REF = t1.REF
但是,從我的理解,你會不能/允許向表中添加額外的(計算)字段?! 添加另一張可容納此信息的表,以便您可以使用它來鏈接信息也是一種解決方案,但它會增加一些複雜性以確保數據始終保持最新!但是,無論如何,從我的理解,這裏不是一個選項。 另一個解決方法可能是創建一個視圖,以重新映射TRAN及其REF-equivalent。您可以實現所述視圖並將其用作連接中的鏈接。這就像計算的字段方法一樣,總是能夠獲得最新的好處,而不需要額外的邏輯和/或對已有邏輯的改變。
最後,基於Wernfrieds的建議,也許有可能創建一個將TRAN編譯爲REF語法的索引?我沒有這方面的經驗,但它聽起來像是一個選擇。
索引然後將沿
CREATE INDEX ind_ref ON transactions (STORE + '*' + to_char(DATE, 'yy') + '*' + substr(to_char(TRAN), -7)))
線的東西,而你的查詢將隨即成爲這樣的事情:
SELECT *
FROM transactions t1
JOIN transactions t2
ON ((t2.STORE + '*' + to_char(t2.DATE, 'yy') + '*' + substr(to_char(t2.TRAN), -7)) = t1.REF)
,並希望該服務器將然後挑去後指數正確的t2記錄。 但就像我說的,我沒有這方面的經驗,但它是值得拍攝恕我直言。
無論如何,如果所有這些都是nono,而且您只能優化查詢,那麼我會建議儘可能使用STORE和DATE信息來做到最好:
SELECT *
FROM transactions t1
JOIN transactions t2
ON (
t2.store = substr(t1.REF, 1, instr(t1.REF, '*') - 1)
AND t2.DATE BETWEEN to_date('0101' + substr(t1.REF, instr(t1.REF, '*', 1, 1) + 1), instr(t1.REF, '*', 1, 2) - 1)
AND to_date('3112' + substr(t1.REF, instr(t1.REF, '*', 1, 1) + 1), instr(t1.REF, '*', 1, 2) - 1)
AND t2.TRAN % 10000000 = to_number(substr(t1.REF, instr(t1.REF, '*', 1, 2) + 1))
)
思考一下,如果你可以添加該指數
CREATE INDEX ind_tst ON transactions (STORE, DATE, TRAN % 10000000)
那麼它很可能是上面已經查詢是你現在所擁有的相當的改善。並大聲思索這意味着你可以試試這個:
CREATE INDEX ind_tst ON transactions (STORE, to_char(DATE, 'yy'), TRAN % 10000000)
SELECT *
FROM transactions t1
JOIN transactions t2
ON (
t2.store = substr(t1.REF, 1, instr(t1.REF, '*') - 1)
AND to_char(t2.DATE, 'yy') = substr(t1.REF, instr(t1.REF, '*', 1, 1) + 1), instr(t1.REF, '*', 1, 2) - 1)
AND t2.TRAN % 10000000 = to_number(substr(t1.REF, instr(t1.REF, '*', 1, 2) + 1))
)
希望這有助於一點。由於我沒有使用Oracle的經驗,您可能需要修復這裏和那裏的語法,對此感到抱歉......無論如何,祝您好運!
也許這個SO問題會幫助你,閱讀評論也:http://stackoverflow.com/questions/2486952/optimizing-oracle-query?rq=1,但是瓶頸可能在這一行'... to_char(t2.DATE,'yy')...' – bodi0
這種連接是可怕的...... –
解釋計劃將幫助我們排除故障。例如,優化器有可能嚴重低估了聯接的基數,導致了NESTED LOOP而不是HASH JOIN。在這種情況下,USE_HASH(t1 t2)'提示或條件的擴展統計信息可能會有所幫助。但這只是一個沒有執行計劃的瘋狂猜測。 –