トップ  > SQL調査報告  > DECODE関数とCASE文の検証
 



■ DECODE関数とCASE文の検証証  ぽか〜(●・д・●)〜ん…
■ 調査テーマ
 DECODE( )関数については、いまさら、説明の必要はないでしょうが、

    DECODE( A, ptn1, exp1, ptn2, exp2, ...,ptn[n], exp[n], default )

      A が ptn1 に等しい時は exp1 を返えす。
      ptn2 に等しい時は exp2 を返えす。
      ...
      ptnn に等しい時は expn を返えす。
      それら以外 の時は exp1 を返えす。

となっています。

 DECODE( )関数と似ていますが、SELECTリストで条件分岐させる手段に、CASE文があります。

 この2つは、記述方法が違うだけなのか、それともなにか大きな違いが(※パフォーマンスという
観点で)あるのか統計情報を取って比較する。

あらよっと(●・д・●ノ)ノ⌒┻━┻
■ 調査手順
< 手順1 >
 次のテーブルを用意する。
        CREATE TABLE TMP_TBL (
              CLM1 NUMBER
            , CLM2 NUMBER
        ) ;

< 手順2 >
 次のレコードをINSERTする。
        INSERT INTO TMP_TBL VALUES( 1, 1 );
        INSERT INTO TMP_TBL VALUES( 2, 1 );
        INSERT INTO TMP_TBL VALUES( 3, 1 );
        INSERT INTO TMP_TBL VALUES( 1, 2 );
        INSERT INTO TMP_TBL VALUES( 4, 1 );
        COMMIT ;

< 手順3 >
 次のSELECT文を実行し、SELECTされる結果と統計情報を確認する。
        SELECT
            DECODE(CLM1,1,10,2,20,3,30,100) A
        FROM
            TMP_TBL
        WHERE
            CLM2 = 1;

< 手順4 >
 次のSELECT文を実行し、SELECTされる結果と統計情報を確認する。
        SELECT
            CASE WHEN CLM1 = 1 THEN
                10
            ELSE
                CASE WHEN CLM1 = 2 THEN
                    20
                ELSE
                    CASE WHEN CLM1 = 3 THEN
                        30
                    ELSE
                        100
                    END
                END
            END A
        FROM
            TMP_TBL
        WHERE
            CLM2 = 1;
■ 調査結果
 処理の実行結果は以下のようになりました。
< 手順3 結果 >
SQL>  SELECT
    DECODE(CLM1,1,10,2,20,3,30,100) A
FROM
    TMP_TBL
WHERE
    CLM2 = 1;

         A
----------
        10
        20
        30
       100
4行が選択されました。

SQL>

< 手順3 統計情報 >
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        2      0.00       0.00          0          2          4           4
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        4      0.00       0.00          0          2          4           4

< 手順4 結果 >
SQL>  SELECT
    CASE WHEN CLM1 = 1 THEN
        10
    ELSE
        CASE WHEN CLM1 = 2 THEN
            20
        ELSE
            CASE WHEN CLM1 = 3 THEN
                30
            ELSE
                100
            END
        END
    END A
FROM
    TMP_TBL
WHERE
    CLM2 = 1;

         A
----------
        10
        20
        30
       100
4行が選択されました。

SQL>

< 手順4 統計情報 >
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        2      0.00       0.00          0          2          4           4
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        4      0.00       0.00          0          2          4           4

※<処理3> と同じですね。
■ まとめと感想
 結果セットは当然同じですがパフォーマンスも差異無し。より複雑なパターンの場合に差異が出る
のだろうか...
 DECODE( ) はメンテナンスや、コーディングの面でやや何があると言われているが、さすがに慣れ
て、その意見に賛同はしない。
 DECODE( ) の方がSELECT文としてのコーディング量は少ないし、実行解析速度もCASEに比べて 速
いと思われる。
 CASEは 条件に大小関係や、やや複雑な条件も記載できるので汎用性ではDECODE( ) 以上である。

シュッ●三(●・∀・●w)