PostgreSQL:强制数据进入内存

Ada*_*tan 41 postgresql memory cache

有没有一种系统的方法可以强制 PostgreSQL 将特定表加载到内存中,或者至少从磁盘中读取它以便系统缓存它?

Erw*_*ter 44

Postgres 9.4最终添加了一个扩展来将关系中的数据预加载到操作系统或数据库缓冲区缓存中(由您选择):

pg_prewarm

这允许更快地达到完整的操作性能。

在您的数据库中运行一次(此处有详细说明):

CREATE EXTENSION pg_prewarm;
Run Code Online (Sandbox Code Playgroud)

然后很容易预加载任何给定的关系。基本示例:

SELECT pg_prewarm('my_tbl');
Run Code Online (Sandbox Code Playgroud)

查找my_tbl在搜索路径中命名的第一个表并将其加载到 Postgres 缓冲区缓存。

或者:

SELECT pg_prewarm('my_schema.my_tbl', 'prefetch');
Run Code Online (Sandbox Code Playgroud)

prefetch如果支持,向操作系统发出异步预取请求,否则抛出错误。read 读取请求的块范围;与 不同prefetch,这是同步的,并且在所有平台和构建上都受支持,但可能会更慢。buffer将请求的块范围读取到数据库缓冲区缓存中。

默认为buffer,影响最大(成本更高,效果最佳)。

阅读手册了解更多详情
Depesz 也在博客中介绍了它。


DrC*_*sos 32

您可能对邮件列表主题之一感兴趣,由 Tom Lane(核心开发人员)回答:

[..] 但我的观点是,那些认为自己比 LRU 缓存算法更聪明的人通常是错误的。如果表被大量使用,它会留在内存中就好了。如果根据 LRU 算法它没有足够多地用于留在内存中,那么内存空间可能真的应该花在其他东西上。[..]

您可能还对 SO 问题感兴趣:https : //stackoverflow.com/questions/486154/postgresql-temporary-tables,也许更合适/sf/ask/28490451/ -whole-postgresql-database-into-the-ram

  • 是和否。我们将一些 Oracle 表锁定在内存中,因为我们知道它们可能不会经常使用,但在使用它们的情况下,延迟将是一个杀手。DB 应该始终给 DBA 最终决定权(另一个例子是暗示查询优化器)。 (28认同)

Dav*_*ett 5

一般情况下,如果您有足够的 RAM,您通常可以相信数据库服务能够很好地将您经常使用的内容保存在 RAM 中。有些系统允许您提示该表应始终保存在 RAM 中(这对于不经常使用的小型表很有用,但在使用它们时,它们尽快响应很重要),但是如果 pgsql 有这样的表提示使用它们时需要非常小心,因为您会减少可用于缓存其他内容的内存量,因此可能会减慢应用程序的整体速度。

如果您希望在启动时填充数据库的页面缓存(例如在重新启动或其他导致数据库忘记缓存的所有内容的维护操作之后),请编写一个执行以下操作的脚本:

SELECT * FROM <table>
SELECT <primary key fields> FROM <table> ORDER BY <primary key fields>
SELECT <indexed fields> FROM <table> ORDER BY <indexed fields>
Run Code Online (Sandbox Code Playgroud)

(对每个索引或过程重复最后一步,并注意 ORDER BY 子句中的字段顺序正确)

运行上述命令后,每个数据和索引页都应该已被读取,因此将位于 RAM 页面缓存中(至少暂时如此)。我们的应用程序数据库有这样的脚本,这些脚本在重新启动后运行,以便之后登录系统的第一个用户不会遇到响应速度变慢的情况。您最好手写任何此类脚本,而不是扫描数据库定义表(如MSSQL中的sys.objects// ),然后您可以有选择地扫描最常用的索引,而不是扫描所有需要更长时间的索引。sys.indexessys.columns