XML を出力する PL/PGsql ストアド プロシージャで問題が発生しました。
基本的には、クエリの結果をxmlとして出力する関数です。
クエリは十分に高速ですが、結果のセットが大きくなりすぎると、xmlconcat がますます遅くなることがわかりました。
機能を簡略化した内容です。
CREATE OR REPLACE FUNCTION test_function (v_limit int)
RETURNS xml AS
$BODY$
DECLARE
v_rec record;
v_xml xml;
v_query text;
BEGIN
v_query := 'SELECT * FROM test_table LIMIT ' || v_limit;
FOR v_rec IN EXECUTE v_query LOOP
v_xml := xmlconcat(v_xml,
xmlelement(name content, v_rec.content)
);
END LOOP;
RETURN v_xml ;
END
$BODY$
LANGUAGE 'plpgsql' SECURITY DEFINER ;
テーブル test_table には、テキスト型の content という名前のフィールドだけが含まれています。コンテンツの平均の長さは 100 文字です。
この問題は、連結するレコードが大量にある場合に発生します。
この説明分析を見てください。必要な時間は指数関数的に増加します。
db=# explain analyze select test_function(500);
QUERY PLAN
--------------------------------------------------------------------------------------
Result (cost=0.00..0.26 rows=1 width=0) (actual time=42.890..42.893 rows=1 loops=1)
Total runtime: 42.909 ms
(2 rows)
db=# explain analyze select test_function(1000);
QUERY PLAN
----------------------------------------------------------------------------------------
Result (cost=0.00..0.26 rows=1 width=0) (actual time=109.153..109.159 rows=1 loops=1)
Total runtime: 109.178 ms
(2 rows)
db=# explain analyze select test_function(10000);
QUERY PLAN
------------------------------------------------------------------------------------------
Result (cost=0.00..0.26 rows=1 width=0) (actual time=8304.257..8304.277 rows=1 loops=1)
Total runtime: 8304.298 ms
(2 rows)
xmlconcat を使用しない単一のクエリのコストは、10000 レコードに対してわずか 36 ミリ秒です。
xmlconcat の効率を改善するための提案はありますか?
サーバーのバージョンは 8.3.6 です... xmlagg 機能を利用できません