我需要执行250万次查询.此查询生成我需要的一些行,AVG(column)
然后使用它AVG
来从低于平均值的所有值中过滤表.然后我需要将INSERT
这些过滤结果放入表格中.
以合理的效率执行此类操作的唯一方法似乎是TEMPORARY TABLE
为每个query-postmaster python-thread 创建一个.我只是希望这些TEMPORARY TABLE
s不会被持久化到硬盘驱动器(根本)并且将保留在内存(RAM)中,当然,除非它们没有工作内存.
我想知道TEMPORARY TABLE是否会引发磁盘写入(这会干扰INSERTS,即整个进程缓慢)
请注意,在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
经常使用临时表时我还应该担心什么?在使用DROPped临时表后,建议使用vacuum,以清除目录中的任何死元组.使用默认设置(auto_vacuum
)时,Postgres将每隔3分钟左右自动吸尘.
此外,与您的问题无关(但可能与您的项目有关):请记住,如果您必须在填充后对临时表运行查询,那么最好创建适当的索引并发出一个ANALYZE
on 完成插入后的临时表.默认情况下,基于成本的优化器将假定新创建的临时表具有~1000行,如果临时表实际包含数百万行,则可能导致性能较差.
临时表只提供一个保证 - 它们在会话结束时被删除.对于小型表,您可能在后备存储中拥有大部分数据.对于大型表,我保证数据将定期刷新到磁盘,因为数据库引擎需要更多的工作空间来处理其他请求.
编辑:如果你完全需要只有RAM的临时表,你可以在RAM磁盘上为数据库创建一个表空间(/ dev/shm works).这减少了磁盘IO的数量,但要注意,如果没有物理磁盘写入,目前无法执行此操作; 创建临时表时,数据库引擎会将表列表刷新到稳定存储.