有没有一种系统的方法来强制PostgreSQL将特定表加载到内存中,或者至少从磁盘中读取它以便系统将其缓存?
有没有一种系统的方法来强制PostgreSQL将特定表加载到内存中,或者至少从磁盘中读取它以便系统将其缓存?
Answers:
您可能对邮件列表主题之一有兴趣,Tom Lane(核心开发人员)回答了这个问题:
[..]但是我的观点是,认为自己比LRU缓存算法更聪明的人通常会犯错误。如果该表被大量使用,它将留在内存中就好了。如果根据LRU算法,它没有足够多地用于保留在内存中,则可能确实应该将内存空间用于其他方面。[..]
您可能还会对一个SO问题感兴趣:https : //stackoverflow.com/questions/486154/postgresql-temporary-tables,也许更适合https://stackoverflow.com/questions/407006/need-to-load-the整个postgresql数据库到公羊
Postgres 9.4最终添加了扩展,以将数据从关系预加载到OS或数据库缓冲区高速缓存中(由您选择):
pg_prewarm
这样可以更快地达到完整的运行性能。
在您的数据库中运行一次(此处的详细说明):
CREATE EXTENSION pg_prewarm;
然后,很容易预加载任何给定的关系。基本示例:
SELECT pg_prewarm('my_tbl');
查找my_tbl
在搜索路径中命名的第一个表并将其加载到Postgres缓冲区高速缓存中
要么:
SELECT pg_prewarm('my_schema.my_tbl', 'prefetch');
prefetch
向操作系统发出异步预取请求(如果支持),否则引发错误。read
读取请求的块范围;不像prefetch
,它是同步的,并且在所有平台和构建版本上都受支持,但可能会更慢。buffer
将请求的块范围读入数据库缓冲区高速缓存。
默认值为buffer
,其影响最大(成本更高,效果最好)。
请阅读手册以获取更多详细信息,引号位于此处。
Depesz也对此发表了博客。
通常,如果您有足够的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>
(为每个索引或课程重复执行最后一步,请注意以正确的顺序排列ORDER BY子句中的字段)
运行以上命令后,应该已经读取了每个数据页和索引页,因此应该在RAM页缓存中(至少暂时)。对于我们的应用程序数据库,我们有这样的脚本,这些脚本在重新启动后运行,这样,以后首次登录系统的用户就不会出现响应速度变慢的情况。您最好直接手写任何此类脚本,而不是扫描数据库定义表(如MSSQL中的sys.objects
/ sys.indexes
/ sys.columns
),然后可以有选择地扫描最常用的索引,而不是扫描将花费更长的时间的所有索引。
SELECT * FROM schema.table
并看到它将整个60GiB表加载到我的100GiB PostgreSQL缓冲区缓存中。
我遇到了类似的问题:
重新启动服务器服务并丢弃了所有兑现的数据后,许多查询在第一次调用时就特别慢,这是因为查询的特定复杂性,直到所有必需的索引和数据被兑现。这意味着,例如,用户必须对每个“项目”(执行时间1-3秒)和来自5000万行的相关数据进行一次命中,因此用户将不再遭受任何不必要的延迟。用户需要花费前3个小时才能体验到令人讨厌的挂起,直到大多数使用的数据被兑现并且程序破坏了生产性能的一流水平,即使如此,结束时也只有2天,突然遇到了短暂的延迟,当您遇到较少的首次访问数据时... ,用于统计数据等。
为了解决这个问题,确实编写了一个小的python脚本,该脚本在具有大索引的最重使用表上执行选择。运行仅需15分钟,并且没有性能延迟。
嗯,可能是COPY命令会有所帮助。只需执行COPY到stdout并从中读取。可以使用pg_dump来做到这一点:
pg_dump -U <user> -t <table> <database> > /dev/null
另一种方法是查找所有表文件并运行cat <files> > /dev/null
。
这是有关如何获取表文件名的示例:
# SELECT oid, datname FROM pg_database ;
oid | datname
-------+-----------
<...>
16384 | test
-- out of database is 16384
# SELECT oid, relname FROM pg_class WHERE relname like 'fn%';
oid | relname
-------+---------
24576 | fn
(1 row)
-- oid of our table is 24576
因此,表格的文件是/ path / to / pgsql / data / base / 16384/24576 *
您米格思还想读取索引和烤面包表,以相同的方式获取它们的oid。
顺便说一句,您为什么需要它?我相信postgresql和OS足够聪明,可以缓存最新数据并保持良好状态。缓存效率。