PostgreSQL内存中的临时表缓存?

5

背景:

我想在一些临时表中存储一些临时结果。这些表可能会在时间上接近的几个查询中被重复使用,但是在某些时候,我使用的进化算法可能不再需要一些旧表,并继续生成新表。将会有多个查询,可能同时使用这些表。只有一个用户执行所有这些查询。我不知道这是否澄清了关于会话等方面的所有内容,我仍然不确定它的工作原理。

目标:

我想要做的是创建临时表(如果它们不存在),尽可能将它们存储在内存中,如果在某些时候没有足够的内存,则删除那些将提交到硬盘的表(我猜这些将是最近最少使用的)。

示例:

客户端将使用不同的参数进行查询EMAs,并使用不同的系数对它们进行聚合,每个个体的系数和EMA的参数可能会重复,因为它们仍然在基因池中,而且可能在一段时间后不再需要。还将有更多参数的类似查询,遗传算法将为参数找到正确的值。

问题:

  • 这就是“on commit drop”的意思吗?我看过有关会话和事务的描述,但我真的不理解这些概念。如果问题很愚蠢,请原谅。
  • 如果不是,您是否知道任何简单的方法让Postgres执行此操作?

解决方法:

在最坏的情况下,我应该能够估计出可以在内存中保留多少表,并尝试自己实现LRU,但它永远不会像Postgres那样好。

非常感谢。


我猜唯一保存在内存中的东西是操作系统磁盘缓存,而且除了配置设置之外,Postgresql对内存的使用没有直接的程序员控制。展示用户将要执行的查询,以便建立数据库设计和优化。否则,该问题可能会被关闭为“不具有建设性”。如果客户端很富裕,可以考虑在客户端保留状态。 - Clodoaldo Neto
以下是一些可能有价值的额外信息:http://raghavt.blogspot.com/2012/04/caching-in-postgresql.html。 - Kuberchaun
数据库不是运行进化算法的好地方。你真的应该将临时数据缓存在客户端程序内存中,而不是在数据库中。例如,您可以使用memcached进行并行访问。在Postgres中,临时表只能从一个客户端访问,因此无法实现并发。当客户端程序断开连接时,它们也会被删除。 - Tometzky
@Clodoaldo,从客户端进行操作是可能的,我只是希望Postgres能够为我完成这项工作,并以一种非常优化和高效的方式进行,以便我不必再次编写程序。 - Trylks
@Tometzky 为一个单独的客户端创建临时表可能是一个解决方案。 - Trylks
1个回答

4
这是一个复杂的话题,可能需要深入讨论。我认为值得解释一下为什么PostgreSQL不支持这个功能,以及最近版本中可以用什么方法接近你想要实现的目标。
PostgreSQL有一个非常好的方法来缓存多用户间的各种数据集。一般情况下,你不希望允许程序员指定将临时表保留在内存中,如果它变得非常大。然而,临时表的管理方式与普通表有很大的不同,因为它们是:
1. 由单个后端缓冲,而不是共享缓冲区 2. 仅本地可见 3. 未记录
这意味着通常情况下,你不需要为临时表生成大量的磁盘I/O。这些表通常不会刷新WAL段,并且由本地后端管理,因此它们不会影响共享缓冲区的使用。这意味着只有在必要时才会偶尔将数据写入磁盘,通常是为了释放内存以供其他(通常更频繁)的任务使用。你当然不会强制进行磁盘写入,只有在其他事物使用完内存后才需要进行磁盘读取。
最终的结果是,你不需要真正担心这个问题。PostgreSQL已经尝试在一定程度上做到你要求它做的事情,临时表的磁盘I/O需求比标准表要低得多。但是它不会强制表保留在内存中,如果它们变得足够大,页面可能会过期进入操作系统的磁盘缓存,最终进入磁盘。这是一个重要的功能,因为它确保了当许多人创建许多大型临时表时性能可以优雅地降级。

有一些我不太理解的地方。在临时表的情况下,我应该指定什么行为?(on commit preserve rows?)如果我有太多的临时表,是否可以从磁盘中删除它们?我不确定根据on commit子句的不同规范,数据过期到不同的位置会产生什么后果。我计划对所有这些临时表使用create if not exists,所以如果它们被删除,那应该不是问题,除了重新计算它们的时间。 - Trylks
这取决于你的使用情况。如果你要保留行,那么最终刷新到磁盘的可能性更高,但是如果你需要跨事务使用它们,你就需要保存这些行。 - Chris Travers
好的,最后一个问题,我能否设置临时表的数量限制或者磁盘中为临时表保留的大小?如果不能,是否有手动删除它们的方法?如果太多的表存储在磁盘上时间过长,这可能会潜在地占用磁盘中的所有空间。 - Trylks
临时表在会话结束时被删除。您可以强制结束会话。如果磁盘空间是一个主要问题,您可以将临时表放在小磁盘分区的表空间中。 - Chris Travers
我想我会使用常规表格。这似乎是我能够拥有表格缓存并在超过一定数量的表格时删除LRU的唯一方法,例如1000。我希望Postgres足够聪明,可以将最近使用且适合内存空间的表格保留在内存中。我将检查配置参数以尝试优化它。谢谢 :) - Trylks
临时表的最大区别在于其他后端不知道它们的存在或内容。如果您需要跨后端进行管理,则临时表不是正确的解决方案。通常,PostgreSQL缓存会尝试将最近使用的内容保留在内存中。如果您遇到问题,请尝试增加shared_buffers。原因是PG缓存比操作系统磁盘缓存更全面、更聪明,但这也带来了计算成本。 - Chris Travers

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