PostgreSQL临时表

时间:2009-01-28 01:40:11

标签: performance postgresql optimization temp-tables

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

以合理的效率执行此类操作的唯一方法似乎是为每个query-postmaster python-thread创建一个TEMPORARY TABLE。我只是希望这些TEMPORARY TABLE不会被持久存储到硬盘驱动器(根本不会)并保留在内存(RAM)中,当然,除非它们没有工作内存。

我想知道TEMPORARY TABLE是否会产生磁盘写入(会干扰INSERTS,即整个进程缓慢)

2 个答案:

答案 0 :(得分:101)

请注意,在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选项
  • 经常使用临时表时我还应该担心什么?在使用DROPped临时表后,建议使用vacuum,以清除目录中的任何死元组。使用默认设置(auto_vacuum)时,Postgres将每隔3分钟左右自动吸尘。

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

答案 1 :(得分:15)

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

编辑: 如果您完全需要只有RAM的临时表,则可以在RAM磁盘上为数据库创建表空间(/ dev / shm works)。这减少了磁盘IO的数量,但要注意,如果没有物理磁盘写入,目前无法执行此操作;创建临时表时,数据库引擎会将表列表刷新到稳定存储区。