目前 Postgres 12.5 上有一个非常大的表,包含超过 22 亿行。表的总大小(包括索引)为 500 GB。我们需要执行一个查询,以便从数据集中找到一组有效行并对它们进行更新。该查询看起来像这样:
select id, col4 from table where col1=$1 and col2=$2 and col3='f' and col4>0 order by col5 limit 10
Run Code Online (Sandbox Code Playgroud)
为了服务此查询,表上有一个索引ON (col1, col2, col5)
,并且查询使用此索引。到目前为止,一切都很好。当缓冲区未命中时数据库需要执行大量磁盘查找时,就会出现问题。这会导致查询等待DataFileRead
。
到目前为止,我们使用的是 16 vCPU 和 128 GB 的机器,存储类型为 io1,预配置 IOPS 为 20000 进行托管(托管在 AWS RDS 上)。我们一开始配置的 IOPS 约为 3000,并不断增加它,希望通过积极的自动清理和数据本地化,它能够稳定在某个值。autovacuum 的配置方式是每隔几天在此表上运行一次。我们最近遇到一个问题,读取 IOPS 开始达到 20000,并且应用程序变得太慢。由于我们无法再在之前的机器上提供超过 20000 的 IOPS,因此我们升级到了一台更大的机器,其大小恰好是原来的两倍。
在较大的计算机上,我们观察到即使读取 IOPS 现在也已降至约 5000,并且该计算机现在在峰值时间消耗的总体 IOPS 约为 6000,并且查询时间精确地减半。我们假设,这肯定与shared_buffer
postgres 现在可用于将热引用行保留在缓存中的更高版本有关。
问题是我们现在使用的机器以大约 5% 的 CPU 负载运行,并且还有 184 GB 的 RAM 仍未使用。总而言之,这台机器的利用率严重不足。我们希望通过对参数进行任何更改来使用较小的机器,以便该查询可以在一些可容忍的延迟限制下运行。我们在之前的机器上尝试过多次内存调整,以充分利用RAM。但增加到shared_buffer …