クエリ内の特定の列をフォーマットするために SQL 関数を呼び出す必要があるクエリがあります。必要なフォーマットは、電話番号のフォーマットと非常によく似ています。に変わり1234567890
ます(123)456-7890
。
selectステートメントから関数を呼び出すとパフォーマンスが低下する可能性があることを読んだことがありますが、それは私の状況に反映されており、クエリにかかる時間は3倍以上になり、関数にこれほど時間がかかるとは思いませんでした. 関数は線形時間で実行されますが、SQL ループを使用します。データベースのサイズを把握するために、この特定のクエリは約 220,000 行を返します。関数を呼び出さずに実行した場合と、関数を呼び出して実行した場合のクエリの実行時間は、< 3 秒から > 9 秒になりました。書式設定が必要な列は、インデックスが作成されていないか、結合条件または where 句で使用されていません。
ここでのパフォーマンスの低下は予想されるものですか、それとも改善するためにできることはありますか?
これは問題の機能です:
CREATE OR REPLACE FUNCTION fn(bigint)
RETURNS character varying LANGUAGE plpgsql AS
$BODY$
DECLARE
v_chars varchar[];
v_ret varchar;
v_length int4;
v_count int4;
BEGIN
if ($1 isnull or $1 = 0) then
return null;
end if;
v_chars := regexp_split_to_array($1::varchar,'');
v_ret := '';
v_length := array_upper (v_chars,1);
v_count := 0;
for v_index in 1..11 loop
v_count := v_count + 1;
if (v_index <= v_length) then
v_ret := v_chars[v_length - (v_index - 1)] || v_ret;
else
v_ret := '0' || v_ret;
end if;
if (v_count <= 6 and (v_count % 2) = 0) then
v_ret := '.' || v_ret;
end if;
end loop;
return v_ret;
END
$BODY$