Postgres表函数的索引结果

时间:2016-12-01 07:07:17

标签: postgresql

我正在寻找创建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函数返回“表格”,而不仅仅是查询结果?

  1. 我正在使用一个函数来构建临时表而不是物化视图来解决“where clause doesn't get pushed into view that contains aggregation”问题。
  2. 我可以创建临时表,然后在所有查询中直接引用它,但这意味着必须构建某种阻塞机制以确保查询不会过早执行,而工具我就是使用不能很好地支持这种机制。

1 个答案:

答案 0 :(得分:0)

您可以尝试指示

的修饰符STABLE
  

STABLE表示该函数无法修改数据库,并且在单个表扫描中,它将始终为相同的参数值返回相同的结果,但其结果可能会在SQL语句中发生更改。

较新的 Postgres版本也支持物化视图。您可以为连接创建实体化视图。 AFAIK物化视图也支持索引。