【发布时间】:2014-02-11 09:39:18
【问题描述】:
我有一个使用非常昂贵的 plsql 函数进行大量递归计算的查询:
SELECT a, b, expensive_recursion(c, d, e) FROM my_table
函数expensive_recursion() 的plpgsql 是这样的:
CREATE OR REPLACE FUNCTION expensive_recursion(col varchar, parent varchar, date varchar)
RETURNS integer AS
$BODY$
DECLARE
_value integer;
_rec record;
BEGIN
-- get the value for the current parent that matches the range
EXECUTE 'SELECT value_'||col||' FROM foo WHERE foo.id = '||quote_literal(parent)||' AND foo.range = '||quote_literal(range) INTO _value;
-- get all children of parent and sum their values
FOR rec IN EXECUTE 'SELECT child FROM relationships WHERE parent = '||quote_literal(parent) LOOP
_value = _value + expensive_recursion(col, rec.child, range);
END LOOP;
RETURN _value;
END;
$BODY$
LANGUAGE plpgsql STABLE COST 1000;
虽然这可行,但我希望不仅为当前正在递归的行启用缓存,还为当前查询中的所有行启用缓存,并在查询完全执行后清除缓存。
例如,带有一些伪代码的原始函数: 创建或替换函数昂贵的递归(col varchar,父 varchar,范围 varchar) 返回整数 AS $身体$ 宣布 _value 整数; _rec 记录; 开始
-- pseudo-code to check the cache and get the cached value or insert into cache
IF parent AND range IN cache
RETURN SELECT value FROM cache WHERE cache.parent = parent and cache.range = range;
END IF;
-- get the value for the current parent that matches the range
EXECUTE 'SELECT value_'||col||' FROM foo WHERE foo.id = '||quote_literal(parent)||' AND foo.range = '||quote_literal(range) INTO _value;
-- get all children of parent and sum their values
FOR rec IN EXECUTE 'SELECT child FROM relationships WHERE parent = '||quote_literal(parent) LOOP
_value = _value + expensive_recursion(col, rec.child, range);
END LOOP;
-- put new value in cache
INSERT INTO cache (value, parent, range) VALUES (_value, parent, range);
-- final value with sum for parent and its children
RETURN _value;
END;
$BODY$
LANGUAGE plpgsql STABLE COST 1000;
有没有办法做到这一点并创建/删除缓存?我可以使用临时表还是我在 plpgsql 函数中管理的某些结构/类型。诀窍是多个用户可以执行此功能,并且由于特定于应用程序的原因,缓存不能跨查询共享。
【问题讨论】:
标签: sql postgresql caching