创建一个临时表(如果不存在)以用于自定义过程

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 ...。就效率而言,这肯定不是一个关键问题。

以上是关于创建一个临时表(如果不存在)以用于自定义过程的主要内容,如果未能解决你的问题,请参考以下文章

临时表和全局临时表

存储过程中新建临时表的

SQL Server 表变量和临时表的区别

检查是否存在临时表,并在创建临时表之前删除它是否存在

如何判断一个临时表是不是存在呢?

mysql临时表