サイトアイコン こじりふぁ

LISTAGGとXMLAGGの処理速度検証

LISTAGGでは4000バイトを超える結果はエラーとなるため、XMLAGGを使えば回避できますが、処理速度はどれぐらいの違いかあるのが気になったので検証してみました。

1万件のデータを準備して検証しています。

LISTAGGを使った検証SQL

SELECT
    DEPT
  , LISTAGG(NAME, ',')
    WITHIN GROUP (ORDER BY NAME) NAME
FROM
    TB_SAMPLE
GROUP BY
    DEPT
;

XMLAGGを使った検証SQL

SELECT
    DEPT
  , RTRIM(
        XMLAGG(
            XMLELEMENT(e, NAME || ',').EXTRACT('//text()')
        ).GetClobVal(), ','
    ) AS RESULT
FROM
    TB_SAMPLE
GROUP BY
    DEPT
;

処理速度結果

回数/平均 LISTAGG XMLAGG
1回目 0.21秒 1.28秒
2回目 0.21秒 1.26秒
3回目 0.21秒 1.26秒
平均 0.21秒 1.27秒

XMLAGGのLISTAGGよりも方が約1秒遅いという結果になりました。

大量データを扱う場合や、高速なレスポンスを要求されるような場合はなるべくLISTAGGを使った方が良さそうです。

SQLの結果が4000バイトを超えないと確証がある場合はLISTAGGを使った方が良いですね。

最後にLISTAGGとXMLAGGの実行計画を確認します。

LISTAGGの実行計画

実行計画
----------------------------------------------------------
Plan hash value: 952551132

--------------------------------------------------------------------------------
| Id  | Operation          | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |           | 10000 |    19M|    12   (9)| 00:00:01 |
|   1 |  SORT GROUP BY     |           | 10000 |    19M|    12   (9)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| TB_SAMPLE | 10000 |    19M|    11   (0)| 00:00:01 |
--------------------------------------------------------------------------------

Note
-----
   - dynamic statistics used: dynamic sampling (level=2)


統計
----------------------------------------------------------
          0  recursive calls
          0  db block gets
         38  consistent gets
          0  physical reads
          0  redo size
101878 bytes sent via SQL*Net to client 641 bytes received via SQL*Net from client
5 SQL*Net roundtrips to/from client 1 sorts (memory) 0 sorts (disk) 48 rows processed

XMLAGGの実行計画

実行計画
----------------------------------------------------------
Plan hash value: 952551132

--------------------------------------------------------------------------------
| Id  | Operation          | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |           | 10000 |    19M|    12   (9)| 00:00:01 |
|   1 |  SORT GROUP BY     |           | 10000 |    19M|    12   (9)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| TB_SAMPLE | 10000 |    19M|    11   (0)| 00:00:01 |
--------------------------------------------------------------------------------

Note
-----
   - dynamic statistics used: dynamic sampling (level=2)
   - Unoptimized XML construct detected (enable XMLOptimizationCheck for more information)


統計
----------------------------------------------------------
          0  recursive calls
          0  db block gets
         38  consistent gets
          0  physical reads
          0  redo size
39399 bytes sent via SQL*Net to client 31136 bytes received via SQL*Net from client
146 SQL*Net roundtrips to/from client 1 sorts (memory) 0 sorts (disk) 48 rows processed

赤枠のところですが、XMLAGGの方が数値が高くなっています。XMLAGGはクライアントとの送受信回数が増えて遅くなってしまうようです。