使用临时表替换 WHERE IN 子句

3

我需要查询一个表中用户输入的值列表。这个列表可能非常大,而且长度在编译时是未知的。为了提高效率,我想使用一个临时表并对其执行连接操作,而不是使用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;

如果我同时有两个线程在执行,那么当第二个线程试图在第一个线程之后创建TEMP表时,会不会出现错误?

我是否应该随机生成一个TEMP表的名称呢?

或者,如果将整个操作包装在一个事务中,是否可以解决命名冲突?

这是Postgresql 8.2版本。

谢谢!

2个回答

3

不必担心冲突问题。

pg_temp架构是会话特定的。如果你在另一个会话中有并发语句,则会使用不同的架构(即使您看到它具有相同的名称)。

然而,有两点需要注意:

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

    因此,对于小数据集/频繁使用来说,最好坚持使用“in”或“with”语句(Postgres都能很好地处理)。有时候使用不可变的返回函数可以欺骗规划器使用您正在寻找的任何计划。

  2. 如果您决定实际使用临时表,则最好在填充它们后对其进行索引和分析。否则,您只是写了一个“with”语句。


2

啊,我看到我忘了提到我正在使用的是8.2版本,这个版本好像没有WITH语句。但是VALUES语句看起来也很有用:http://www.postgresql.org/docs/8.2/interactive/queries-values.html - Jonathan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接