86

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

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

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

4

2 回答 2

125

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

但是,临时表在数据库会话结束时被删除

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

您必须考虑多个因素:

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

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

于 2009-02-17T05:48:31.833 回答
21

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

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

于 2009-01-28T06:19:04.597 回答