web-dev-qa-db-ja.com

WHEN全体を括弧で囲むことにより、DB2 CASEステートメントが高速になりました。

遅いクエリを最適化しようとすると、私のチームの誰かがこれに遭遇しました。これをストアドプロシージャに含めると、次のようになります。

CASE 
  WHEN MYCOL BETWEEN @STARTNUM AND @ENDNUM 
    AND RECTYPE = 'RO' 
    THEN 1 
    ELSE 0 
END AS MYRESULT

これよりも約10秒遅く実行されます。

CASE 
  WHEN (MYCOL BETWEEN @STARTNUM AND @ENDNUM 
    AND RECTYPE = 'RO') 
    THEN 1 
    ELSE 0 
END AS MYRESULT

唯一の違いは、WHEN句全体を囲む括弧です。私たちは何が起こっているのか途方に暮れています。これは、iSeries上のDB2の場合です。

このパフォーマンスの違いを引き起こしているものは何でしょうか、そしてそれをどのように利用して速度を上げることができますか?プログラマーとして、それらの余分な括弧は何も意味しません。 DbAとして、パフォーマンスにそのような劇的な影響を与えるためにオプティマイザがここで何をすることができますか?


編集:これがクエリです。かなり厄介ですが、それは私たちが操作する必要があるデータです。 (ユニオンの前に)単一のサブ選択のみを実行しましたが、それでもパフォーマンスに大きな違いがあったため、ユニオンと最終選択がパフォーマンスに大きな影響を与えていません。
一部の日付操作を修正して、関数呼び出しを削除できることに気づきました。誰かが最終的にそれに到達するでしょう。

SELECT
ID ,
ABBREVIATION ,
METRICS.NAME ,
METRICS.TYPE AS TYPE_ID ,
JOBTYPE.NAME AS TYPE_NAME ,
SUM ( CREATEDORDUE ) AS CREATEDORDUE ,
SUM ( COMPLETED ) AS COMPLETED ,
SUM ( COMPLETEDINSIDE ) AS COMPLETEDINSIDE ,
SUM ( CASE WHEN DAYS <= 7 THEN 1 ELSE 0 END ) AS ONTIME ,
SUM ( CASE WHEN DAYS > 7 AND DAYS <= 14 THEN 1 ELSE 0 END ) AS ONEWEEKLATE ,
SUM ( CASE WHEN DAYS > 14 AND DAYS <= 21 THEN 1 ELSE 0 END ) AS TWOWEEKSLATE ,
SUM ( CASE WHEN DAYS > 21 THEN 1 ELSE 0 END ) AS MORETHANTWOWEEKSLATE

FROM (

-- Active File -- 

SELECT EQMDOM AS ID ,
CT1TID AS ABBREVIATION ,
CT1NAM AS NAME ,
JBCTL ,
JBWKA AS TYPE ,
CASE 
    WHEN JBCDT BETWEEN @STARTDATENUM AND @ENDDATENUM THEN 1 
    ELSE 0 
END AS COMPLETED ,
1 AS CREATEDORDUE ,
-- Stackexchange question
CASE 
    WHEN ( JBCDT BETWEEN @STARTDATENUM AND @ENDDATENUM AND JBDTC = 'RO' ) THEN 1
    ELSE 0 
END AS COMPLETEDINSIDE ,
-- /Stackexchange question
MASTER.USDATE_DATEDIFFERENCE ( 
    CASE WHEN JBCDT = 0 THEN @ENDDATENUM WHEN JBCDT > @ENDDATENUM THEN @ENDDATENUM ELSE JBCDT END , 
    CAST ( MASTER.DATETOCYMDDATE ( DATE ( JBCRT ) ) AS DEC ( 7 , 0 ) ) , 
    CAST ( 'DAYS  ' AS CHAR ( 6 ) ) 
    ) AS DAYS

FROM EMJOB
JOIN EMEQM ON JBUNT = EQMNUM
JOIN TABLE ( MASTER.CSVTABLE ( @LOCATIONS ) ) AS LOCATIONS ON VAL = EQMDOM --CSVTABLE function separates a csv list into a usable table
JOIN AAP030 ON CT1NUM = EQMDOM

WHERE JBSYS = 'PM'
AND ( JBCDT >= MASTER.DATETOCYMDDATE ( DATE ( @STARTDATE ) ) OR JBCDT = 0 )
AND JBCRT <= @ENDDATE 
AND JBCRT > '2012-01-01-00.00.00.000000'  -- bad data before 2012
AND JBSTS <> 'D'

UNION

-- History File -- 

SELECT
EQMDOM AS ID ,
CT1TID AS ABBREVIATION ,
CT1NAM AS NAME ,
JHCTL ,
JHWKA AS TYPE ,
CASE WHEN JHCDT BETWEEN @STARTDATENUM AND @ENDDATENUM THEN 1 ELSE 0 END AS COMPLETED ,
1 AS CREATEDORDUE ,
-- Stackexchange question
CASE 
    WHEN ( JHCDT BETWEEN @STARTDATENUM AND @ENDDATENUM AND JHDTC = 'RO' ) THEN 1 
    ELSE 0 
END AS COMPLETEDINSIDE ,
-- /Stackexchange question
MASTER.USDATE_DATEDIFFERENCE ( 
    CASE WHEN JHCDT = 0 THEN @ENDDATENUM WHEN JHCDT > @ENDDATENUM THEN @ENDDATENUM ELSE JHCDT END , 
    CAST ( MASTER.DATETOCYMDDATE ( DATE ( JHCRT ) ) AS DEC ( 7 , 0 ) ) , 
    CAST ( 'DAYS  ' AS CHAR ( 6 ) ) 
    ) AS DAYS

FROM EMJOBH
JOIN EMEQM ON JHUNT = EQMNUM
JOIN TABLE ( MASTER.CSVTABLE ( @LOCATIONS ) ) AS LOCATIONS ON VAL = EQMDOM
JOIN AAP030 ON CT1NUM = EQMDOM

WHERE
JHSYS = 'PM'
AND ( JHCDT >= MASTER.DATETOCYMDDATE ( DATE ( @STARTDATE ) ) OR JHCDT = 0 )
AND JHCRT <= @ENDDATE 
AND JHCRT > '2012-01-01-00.00.00.000000'
AND JHSTS <> 'D'

)
AS METRICS
JOIN JOBTYPES AS JOBTYPE
    ON METRICS.TYPE = JOBTYPE.TYPE
GROUP BY METRICS.ID , METRICS.ABBREVIATION , METRICS.NAME , METRICS.TYPE , JOBTYPE.NAME ;
3
skipleam

1つの静的SQL(手順)が同等のSQLよりも適切に実行される状況では、以下を調べます。

a)これが実行の順序に依存するかどうか、つまり、2番目のものは最初の1つからディスクからバッファプールにデータを読み取ることでメリットがありますか?実行順序に関係なく、一方が他方よりも優れている場合、これは当てはまりません。

b)計画は同じですか? 1つのプロシージャが1つの統計セットでコンパイルされ、もう1つのプロシージャが別の統計セットでコンパイルされた場合、異なるプランになる可能性があります。同じ統計を使用して両方の手順を再バインド(または再作成)して、まだ異なるかどうかを確認します

4
Lennart