使用临时表替换 WHERE IN 子句

Jon*_*han 5 sql postgresql transactions temp-tables

我让用户输入我需要在表中查询的值列表。该列表可能非常大,并且长度在编译时未知。我认为使用WHERE ... IN (...)临时表并对其执行联接会更有效,而不是使用它。我在另一个SO问题中读到了这个建议(目前找不到它,但会在找到时进行编辑)。

要点是这样的:

CREATE TEMP TABLE my_temp_table (name varchar(160) NOT NULL PRIMARY KEY);

INSERT INTO my_temp_table VALUES ('hello');
INSERT INTO my_temp_table VALUES ('world');
//... etc

SELECT f.* FROM foo f INNER JOIN my_temp_table t ON f.name = t.name;

DROP TABLE my_temp_table;
Run Code Online (Sandbox Code Playgroud)

如果我同时运行其中两个,那么如果线程 2 尝试在线程 1 之后创建 TEMP 表,我不会收到错误吗?

我应该为 TEMP 表随机生成一个名称吗?

或者,如果我将整个事情包装在一个事务中,命名冲突会消失吗?

这是 PostgreSQL 8.2。

谢谢!

Den*_*rdy 3

无需担心冲突。

pg_temp 模式是特定于会话的。如果您在单独的会话中有并发语句,它将使用不同的架构(即使您认为它具有相同的名称)。

不过有两点需要注意:

  1. 每次创建临时对象时,系统目录都会创建临时架构和对象本身。如果频繁使用,这可能会导致混乱。

    因此,对于小集合/频繁使用,通常最好坚持使用 anin或 awith语句(Postgres 可以很好地处理这两种情况)。通过使用不可变的集合返回函数来“欺骗”规划器使用您正在寻找的任何计划有时也很有用。

  2. 如果您决定实际使用临时表,通常最好在填满临时表后对其进行索引和分析。否则你所做的只不过是写一份with声明。