PostgrSQL 中大表的预缓​​存索引

Kar*_*son 4 postgresql index cache postgresql-12

我有一个包含大约 1000 万行的表,其中包含一个主键和一个定义在其上的索引:

create table test.test_table(
    date_info date not null,
    string_data varchar(64) not null,
    data bigint
    primary key(date_info, string_data));
    create index test_table_idx 
    on test.test_table(string_data);
Run Code Online (Sandbox Code Playgroud)

我有一个使用了的查询test_table_idx

select distinct date_info from test.test_table where string_data = 'some_val';
Run Code Online (Sandbox Code Playgroud)

问题是第一次运行查询最多可能需要 20 秒,而在任何后续运行中都需要 < 2 秒。

有没有办法将整个索引加载到内存中,而不是在第一次访问时获取数据库加载信息?

Erw*_*ter 6

您可以使用附加模块pg_prewarm。每个数据库必须安装一次。看:

它可以“预热”表和索引。要为您的索引执行此操作:

SELECT pg_prewarm('test.test_table_idx');
Run Code Online (Sandbox Code Playgroud)

除非您获得仅索引扫描(您手头的索引没有这样做),否则您可能还想预热表:

SELECT pg_prewarm('test.test_table');
Run Code Online (Sandbox Code Playgroud)

有更多参数可以缩小预热的范围和方式。按照链接操作。

这是昂贵的,并且系统最好将缓存用于其他用途。如果您提前知道确切的查询并且它SELECT没有副作用,您可能只需运行查询来“预热”索引和表的相关数据页。

此外,您最好像这样重新排列 PK 和索引:

    ...
    primary key(string_data, date_info);
    create index test_table_idx on test.test_table(date_info);
Run Code Online (Sandbox Code Playgroud)

现在,PK 索引可以为您提供针对手头查询的仅索引扫描。可能会有很大的不同。看: