複数の週テーブルから単位を読み取る必要がある SQL (postgresql) の関数があります (最大単位数と最大週数)。
単位は、別のテーブルで定義されているいくつかのテーブル (類似) にあります。各テーブルには 22,000,000 を超えるユニットがあります。
いくつかのケースでは、必要なものに十分な単位を取得するために複数のテーブルを検索する必要がありますが、1 つしか必要ない場合もあります。
基本的に、特定の店舗の直近の週からの大きなサンプルが必要です。
現在、次のものがあります。
CREATE OR REPLACE FUNCTION get_units(_cursor REFCURSOR,
_obs_time timestamp without time zone,
_unit_store integer, _unit_limit integer,
_week_limit integer) RETURNS REFCURSOR
LANGUAGE plpgsql
AS $BODY$
DECLARE
_week_cursor REFCURSOR;
_table_name TEXT;
_query_sql TEXT;
_command TEXT := '(SELECT ''0001-01-01'' AS obs_time,
0::smallint detail
WHERE FALSE)';
_week_count INTEGER;
_result_count INTEGER := 0;
_current_unit_limit INTEGER;
BEGIN
OPEN _week_cursor FOR
SELECT table_name
FROM week_table
WHERE create_time < _obs_time
ORDER BY create_time desc
LIMIT _week_limit;
_current_unit_limit := _unit_limit;
LOOP
FETCH _week_cursor INTO _table_name;
EXIT WHEN NOT FOUND;
_query_sql :=
'FROM ' || _table_name || ' u
WHERE u.unit_store = ' || _unit_store || ' ';
EXECUTE 'SELECT count(*) ' || _query_sql || ' LIMIT ' || _current_unit_limit INTO _week_count;
_result_count := _result_count + _week_count;
_current_unit_limit := _unit_limit - _result_count;
IF _week_count > 0 THEN
_command := _command || ' UNION ALL
(SELECT u.obs_time obs_time,
u.detail detail '
|| _query_sql
|| ' ORDER BY u.obs_time DESC'
|| ' LIMIT ' || _week_count || ')';
END IF;
IF (_result_count >= _unit_limit) THEN
EXIT;
END IF;
END LOOP;
CLOSE _week_cursor;
OPEN _cursor FOR EXECUTE _command;
RETURN _cursor;
END;
$BODY$;
ほとんどの場合、結果は良好ですが、いくつかの最悪のシナリオ (数週間ごとに数レコードしかない) では、処理が遅くなります。
何をどのように改善できるか、何か提案はありますか? たとえば、UNION ALL、一時テーブルを削除しますか? 大きな変化をもたらす何か。