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 size101878 bytes sent via SQL*Net to client 641 bytes received via SQL*Net from client5 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 size39399 bytes sent via SQL*Net to client 31136 bytes received via SQL*Net from client146 SQL*Net roundtrips to/from client 1 sorts (memory) 0 sorts (disk) 48 rows processed
赤枠のところですが、XMLAGGの方が数値が高くなっています。XMLAGGはクライアントとの送受信回数が増えて遅くなってしまうようです。