PostgreSQL 临时表

Posted

技术标签:

【中文标题】PostgreSQL 临时表【英文标题】:PostgreSQL temporary tables 【发布时间】:2010-10-03 22:09:53 【问题描述】:

我需要执行 250 万次查询。此查询生成一些我需要AVG(column) 的行,然后使用此AVG 从低于平均值的所有值中过滤表。然后我需要将INSERT 这些过滤后的结果放到一个表格中。

以合理的效率做这样的事情的唯一方法似乎是为每个 query-postmaster python-thread 创建一个TEMPORARY TABLE。我只是希望这些TEMPORARY TABLEs 不会(根本)保存在硬盘驱动器中,并且会保留在内存 (RAM) 中,当然,除非它们的工作内存不足。

我想知道 TEMPORARY TABLE 是否会导致磁盘写入(这会干扰 INSERTS,即整个过程缓慢)

【问题讨论】:

你的问题是什么? 大声笑,对不起。我想知道 TEMPORARY TABLE 是否会导致磁盘写入(这会干扰 INSERTS,即整个过程缓慢)。谢谢! 好的,我刚刚通读了一遍。似乎 TEMPORARY TABLE 确实会引起一些磁盘写入开销......但我仍然想知道整个表的副本是否保留在磁盘上,还是只是元数据保留? 【参考方案1】:

请注意,在 Postgres 中,临时表的默认行为是它们不会被自动删除,并且数据在提交时被持久化。见ON COMMIT

不过,临时表是dropped at the end of a database session:

临时表会在会话结束时自动删除,或者 可选择在当前事务结束时。

您必须考虑多种因素:

如果您确实想在事务结束时显式地 DROP 临时表,请使用 CREATE TEMPORARY TABLE ... ON COMMIT DROP 语法创建它。 在存在连接池的情况下,一个数据库会话可能跨越多个客户端会话;为避免CREATE 中的冲突,您应该删除临时表——在返回池连接之前(例如,通过在事务中执行所有操作并使用ON COMMIT DROP 创建语法), 根据需要(通过在任何 CREATE TEMPORARY TABLE 语句之前加上相应的 DROP TABLE IF EXISTS,它的优点是也可以在外部事务中工作,例如,如果连接用于自动提交模式。) 在使用临时表时,在溢出到磁盘之前,它有多少可以放入内存?请参阅postgresql.conf 中的temp_buffers 选项 经常使用临时表时我还需要担心什么?删除临时表后建议使用真空,以清除目录中的任何死元组。使用默认设置 (auto_vacuum) 时,Postgres 会每隔 3 分钟左右自动为您清理一次。

另外,与您的问题无关(但可能与您的项目有关):请记住,如果您必须在填充临时表 之后对临时表运行查询,那么它是创建适当的索引并在有问题的临时表上发出ANALYZE 的好主意你完成插入它之后。默认情况下,基于成本的优化器会假设新创建的临时表有大约 1000 行,如果临时表实际上包含数百万行,这可能会导致性能不佳。

【讨论】:

好东西。谢谢。我实际上只使用了一个临时表,因为我需要在它上面执行两个不同的 SELECT(所以我想分析是不值得的)。我为操作提供了很多 temp_buffers,但由于许多 python 线程正在创建和删除 TEMP 表,... postgres 在脚本完成其工作时占用了越来越多的 RAM。我发现将 python 线程的数量(在客户端计算机上运行)限制为比 cpu 核心的数量多一点,可以提供最佳(最有效和最有效的)执行时间。再次感谢您的智慧弗拉德。 即使您只在临时表上 SELECT 两次,每次创建临时表时投入几毫秒的索引创建 + ANALYZE 可以节省大量时间/如果将其他表与临时表连接- 将查询手动放入 PgAdminIII 并使用“Query/Explain(F7)”功能。 真的吗?好的,我想我需要有人告诉我尝试一下,因为它似乎违反直觉(设置成本似乎不值得)。不管怎样,谢谢你,下次我会尝试分析分析。我已经看到了 TEMP INDEX 的价值。然而我想知道分析是否真的...... ANALYZE 开销平均为 100 毫秒,您可以按表/列进行配置。您绝对需要一个 ANALYZE 以使优化器不会做出任何愚蠢的假设,假设一百万行表仅包含 100 行并且对它进行表扫描 10 次... :)【参考方案2】:

临时表只提供一种保证——它们在会话结束时被删除。对于一个小表,您可能会将大部分数据放在后备存储中。对于大型表,我保证数据会定期刷新到磁盘,因为数据库引擎需要更多工作空间来处理其他请求。

编辑: 如果您绝对需要仅 RAM 的临时表,您可以在 RAM 磁盘上为您的数据库创建一个表空间(/dev/shm 有效)。这会减少磁盘 IO 的数量,但请注意,目前无法在没有物理磁盘写入的情况下执行此操作;创建临时表时,数据库引擎会将表列表刷新到稳定存储中。

【讨论】:

临时表也没有 WAL 日志记录 rhaas.blogspot.com/2010/05/…

以上是关于PostgreSQL 临时表的主要内容,如果未能解决你的问题,请参考以下文章

Postgresql中临时表(temporary table)的特性和用法

PostgreSQL 临时表是不是已经取消记录?

Postgresql:对 plpgsql 中的临时表执行更新不起作用

PostgreSQL 临时表

Postgresql的临时表的用法

postgresql 中的临时表在所有客户端会话中都可见吗?