我希望创建一个Postgres函数,可以缓存长时间运行查询的结果,这样每个事务只需要执行一次:
CREATE OR REPLACE FUNCTION get_records (
_state VARCHAR(10)
)
RETURNS TABLE (
id UUID
) AS
$$
DECLARE
_temptable VARCHAR;
BEGIN
_temptable := FORMAT('temp_state_%s', _state);
IF NOT EXISTS(SELECT 1 FROM pg_tables WHERE tablename = _temptable) THEN
EXECUTE FORMAT('CREATE TEMPORARY TABLE %I (id UUID NOT NULL, PRIMARY KEY(_uid)) ON COMMIT DROP', _temptable);
EXECUTE FORMAT('INSERT INTO %I SELECT id FROM very_complex_nested_query', _temptable);
EXECUTE FORMAT('ANALYZE %I', _temptable);
END IF;
RETURN QUERY EXECUTE FORMAT('SELECT id FROM %I', _temptable);
END;
$$
LANGUAGE 'plpgsql';
现在,我可以运行所有的查询并连接这个函数:
SELECT mt.*
FROM my_table1 mt
INNER JOIN get_records('new') nr ON mt.id = nr.id
SELECT mt.*
FROM my_table2 mt
INNER JOIN get_records('new') nr ON mt.id = nr.id
SELECT mt.*
FROM my_table3 mt
INNER JOIN get_records('new') nr ON mt.id = nr.id
-- ... many more
我有一堆这样的东西,没有保证哪个会先运行或以什么顺序运行。
这个方法运行得相当好,但是临时表上的主键索引没有被使用。
如何从Postgres函数中返回一个“表”,而不仅仅是查询结果?
- 我正在使用一个函数来构建临时表,而不是使用材料化视图来解决“聚合视图中的where子句不起作用”问题。
- 我可以创建临时表,然后直接引用它在所有的查询中,但这意味着必须构建某种阻塞机制,以确保查询不会过早地执行,而我使用的工具不太支持这样的机制。
sql
函数中。使用该sql
函数的查询可以比PL/pgSQL呈现给优化器的黑匣子更好地进行优化。 - user330315语言sq
而不是语言plpgsql
- 但如果你想给它创建索引,你需要在临时表上创建一个索引。 - user330315