创建一个临时表(如果不存在)以用于自定义过程
Posted
技术标签:
【中文标题】创建一个临时表(如果不存在)以用于自定义过程【英文标题】:Create a temp table (if not exists) for use into a custom procedure 【发布时间】:2014-04-08 06:35:57 【问题描述】:我正在尝试使用临时表:
CREATE OR REPLACE FUNCTION test1(user_id BIGINT) RETURNS BIGINT AS
$BODY$
BEGIN
create temp table temp_table1
ON COMMIT DELETE ROWS
as SELECT table1.column1, table1.column2
FROM table1
INNER JOIN -- ............
if exists (select * from temp_table1) then
-- work with the result
return 777;
else
return 0;
end if;
END;
$BODY$
LANGUAGE plpgsql;
我希望立即或尽快删除行 temp_table1
,这就是我添加 ON COMMIT DELETE ROWS
的原因。显然,我得到了错误:
ERROR: relation "temp_table1" already exists
我尝试添加IF NOT EXISTS
,但我不能,我根本找不到我正在寻找的工作示例。
你的建议?
【问题讨论】:
【参考方案1】:每次创建 TEMP 表之前都 DROP Table 如下:
BEGIN
DROP TABLE IF EXISTS temp_table1;
create temp table temp_table1
-- Your rest Code comes here
【讨论】:
你确定它比 DELETE ROWS 更有效吗? 是的,因为只删除行不会删除表,这样您就无法再次创建此表。 但我不需要。我也在询问性能方面的问题。 我的印象是这是不好的做法,因为您必须将两个表都保存在内存中(如果大小需要,也可以溢出到磁盘),这是正确的吗?还;即使 temp_table1 在 DROP 时不存在,它仍然会由于锁而导致膨胀,对吧?【参考方案2】:临时表的问题在于删除和重新创建临时表会使 pg_attribute 严重膨胀,因此在一个阳光明媚的早晨,您会发现 db 性能下降,而 pg_attribute 200+ gb,而您的 db 将像 10gb。
因此,我们非常重视具有 >500 rps 和通过 nodejs 异步 i\o 的临时表,因此经历了 pg_attribute 非常严重的膨胀。剩下的就是一个非常激进的吸尘器,它会停止性能。 这里给出的所有答案都不能解决这个问题,因为它们都严重膨胀 pg_attribute。
所以解决方案很优雅
create temp table if not exists my_temp_table (description) on commit delete rows;
所以你继续玩临时表并保存你的 pg_attribute。
【讨论】:
【参考方案3】:您想在提交后 DROP 术语表(而不是 DELETE ROWS),所以:
begin
create temp table temp_table1
on commit drop
...
Documentation
【讨论】:
你确定它比 DELETE ROWS 更有效吗? 我相信它比'on commit delete rows' + 'drop table if exists'更有效。 但我真的不需要删除它,只要我可以删除行。为什么我每次都要重新创建它而不是只删除它的行? 不幸的是,在 postgres (postgresql.org/docs/9.2/static/sql-createtableas.html) 中不允许构造create temp table if not exists ... as ...
。就效率而言,这肯定不是一个关键问题。以上是关于创建一个临时表(如果不存在)以用于自定义过程的主要内容,如果未能解决你的问题,请参考以下文章