2014-12-03 55 views
1

使用VBA中的SQL處理DB2數據庫以製作一些自定義報告。我想出了下面的查詢,但花了45分鐘才能運行80,000個結果......表BILLPRC可能在WHERE子句之前總共有兩次。只是想知道是否有更好的方法來編寫查詢來加快速度。這可能是一個相當含糊的問題,所以如果您需要更多信息,我可以進一步解釋。加快JOIN中CASE的SQL查詢

SELECT b.BLCO# || RIGHT('00000' || b.BLACCT, 5) Acct, b.BLRECT Type, b.BLREC# Record, i.INAME || ' ' ||  i.INAME2 Desc, b.BLPPGM# Promo, SUBSTR(b.BLPEFFD, 4, 2) || SUBSTR(b.BLPEFFD, 6, 2) || SUBSTR(b.BLPEFFD, 2, 2)  Eff, SUBSTR(b.BLPENDD, 4, 2) || SUBSTR(b.BLPENDD, 6, 2) || SUBSTR(b.BLPENDD, 2, 2) Exp, CASE 
    WHEN (p.PPPRC1 = '0') THEN (p.PPPRC2) 
    WHEN (p.PPPRC1 != '0') THEN (p.PPPRC1) END Price, 
    CASE 
    WHEN (p.PPPRC1 = '0') THEN (p.PPCST2) 
    WHEN (p.PPPRC1 != '0') THEN (p.PPCST1) END Allow, i.ILASTC Cost 
FROM QS36F.BILLPRC b 
LEFT JOIN QS36F.PROMO p 
    ON b.BLREC# || b.BLPPGM# = p.PPREC || p.PPPGM# 
LEFT JOIN QS36F.ITEM i 
    ON CASE 
    WHEN (b.BLRECT = 'I') AND (b.BLREC# = i.IMFGR || i.ICOLOR || i.IPATT) THEN 1 
    WHEN (b.BLRECT = 'P') AND (b.BLREC# = i.IPRCCD) THEN 1 
    END = 1 
WHERE (b.BLPPGM# != '') AND (b.BLSTS != 'H') 
ORDER BY (b.BLACCT) 

我有一種感覺,沒有給出記錄和CASE被檢查的數量。

+0

你可以使用索引視圖嗎? – userDEV 2014-12-03 18:51:36

+1

要做的第一件事可能是將文件移出QS36F並創建實際的關係表。 System/36環境並不適用於高性能SQL(甚至可能不適用於中等性能)。仔細查看實際的文件定義。 – user2338816 2014-12-04 07:08:24

+0

東西像'b.BLREC#|| b.BLPPGM#= p.PPREC || p.PPPGM#'意味着你有一個多部分密鑰,這違反了良好的規範化實踐。這也意味着你不能使用索引,所以查詢會很慢。你能比較一下列嗎?當'p'爲'null'時,'SELECT CASE'沒有明確列出大小寫。 DB2具有將CYMD日期轉換爲其他格式的實用程序。你的'ON CASE'是一個'OR'條件,這對一些人有幫助。 – 2014-12-04 13:54:50

回答

2

通過在連接條件中重寫WHERE謂詞(b.BLPPGM# != '') AND (b.BLSTS != 'H'),您可能會獲得更好的性能。

如果可能,儘量不要連接用於連接的字段。例如,而不是

LEFT JOIN QS36F.PROMO p 
    ON b.BLREC# || b.BLPPGM# = p.PPREC || p.PPPGM# 

你可以說

LEFT JOIN QS36F.PROMO p 
    ON b.BLREC# = p.PPREC 
    and b.BLPPGM# = p.PPPGM# 

或等價

LEFT JOIN QS36F.PROMO p 
    ON (b.BLREC#, b.BLPPGM#) = (p.PPREC, p.PPPGM#) 

從您的WHERE子句中的邏輯添加

LEFT JOIN QS36F.PROMO p 
    ON (b.BLREC#, b.BLPPGM#) = (p.PPREC, p.PPPGM#) 

當然,這假定相應的積水的字段是相同的類型或兼容的類型,理想情況下這些字段的大小相同。 DB2通常可以自動將一種類型轉換爲另一種兼容類型。字符串類型通常彼此兼容,而數字類型通常彼此兼容。

然後,最重要的是,確保您有正確的索引。 (我對S/36模式環境不太熟悉,但我假設你可以在其上創建索引。)索引也可以在派生列上構建,即。一個表達如串聯。

+0

連接中的連接意味着優化器沒有可選擇的索引,這會降低性能。索引建議(已多次提供)是減少SQL運行時間的典型方法。 – 2014-12-05 12:52:31

+0

這些文件顯然是外部描述的,所以即使鏈接或以前由IDDU數據字典(DTADCT)的文件定義來描述,那麼遺留的事實對於該場景[除了有十進制數據錯誤之外]沒有影響。庫位[QS36F]或操作環境\模式[S/36EE]的位置不限制索引;可以創建[派生]鍵控訪問路徑,而不管模式和庫在哪裏。包含相同連接的派生鍵AccPth應該有資格實現連接。 – CRPence 2015-04-30 19:52:02

1

出於報告目的,請使用materialized query table,除非您無法真正負擔CPU時間。我知道這有點懶,但MQTs適用於您可以獲得每小時更新結果的情況,並且不希望開始規範化和優化數據庫。你有一個工作邏輯,你顯然理解它,所以去吧。

+0

在這樣的情況下,您建議MQT應該採取什麼方式來避免或提高效率?您引用的文章是針對DB2 LUW的,並且對於DB2 for i而言並不總是準確的。這個問題適用於在IBM i上運行的DB2,它具有與DB2 LUW稍有不同的特性。例如,MQT必須是'MAINTAINED BY USER',所以系統不會自動刷新。 – WarrenT 2015-04-30 21:55:38

1

這看起來就像是DB2爲我....你可能要適當地標記它

假設是,你使用了「運行&解釋」在INAV的運行SQL腳本選項,查看是否DB建議任何新的索引?