我们有间歇性的缓慢查询。我们的 PostgreSQL 是否在内存问题上挣扎?

Luc*_*ais 5 postgresql google-cloud-sql

我正在调查一些缓慢的查询,我需要一些帮助来读取我得到的数据。

我们有一个特定的查询,它使用索引并且大多数时候运行得相当快,但是有时它运行得很慢(700 毫秒以上),不知道为什么。

Limit  (cost=8.59..8.60 rows=1 width=619) (actual time=5.653..5.654 rows=1 loops=1)
   ->  Sort  (cost=8.59..8.60 rows=1 width=619) (actual time=5.652..5.652 rows=1 loops=1)
         Sort Key: is_main DESC, id
         Sort Method: quicksort  Memory: 25kB
         ->  Index Scan using index_pictures_on_imageable_id_and_imageable_type on pictures  (cost=0.56..8.58
rows=1 width=619) (actual time=3.644..5.587 rows=1 loops=1)
               Index Cond: ((imageable_id = 12345) AND ((imageable_type)::text = 'Product'::text))
               Filter: (tag = 30)
               Rows Removed by Filter: 2
 Planning Time: 1.699 ms
 Execution Time: 5.764 ms
Run Code Online (Sandbox Code Playgroud)

如果我理解正确的话,我会说查询的几乎全部成本都在索引扫描上,对吗?这对我来说听起来不错,那么为什么同一个查询有时运行得相当慢呢?

我开始认为我们的实例可能无法将整个索引保留在内存中,因此它时不时地使用磁盘。这可以解释缓慢的查询。然而,这超出了我的想象。那有意义吗?

该表有大约 1500 万行,5156 MB大小也大约是 1500 万行。索引为1752 MB. 顺便说一句,它是一个btree索引。

我们的 PostgreSQL 位于“高度可用”的 Google Cloud SQL 实例上。它有 2 个 vCPU 和 7.5 GB RAM。我们的整个数据库大小约为 35 GB。

CPU 消耗几乎不会超过 40%。通常稳定在20-30%左右。

检查实例内存图表,我注意到消耗量增长到约 4 GB,然后下降到约 700 MB,并再次开始增长。这是一个重复的模式。

理论上,该实例有 7.5 GB RAM,但我不知道所有这些 RAM 是否都适用于 PostgreSQL。不管怎样,大约 3.5 GB 仅用于操作系统听起来相当高,对吧?

内存图

我读到这些配置很重要,因此将它们放在这里(Cloud SQL 默认值):

shared_buffers                             | 318976
temp_buffers                               | 1024
work_mem                                   | 4096
Run Code Online (Sandbox Code Playgroud)

考虑到我们还有一堆其他表和索引,如果一个索引单独为 1.7 GB,那么整个实例的 7.5 GB 是否太低了?

有什么方法可以断言我们是否有内存问题吗?

我感谢您的帮助。

Fer*_*ona 0

我认为正如你所说,更多的是记忆问题。检查你的图表,我可以说大多数时候你的数据库使用分配的 4GB 内存,并且当你运行查询时 postgres 必须使用磁盘。

我想您的查询在低于内存限制时运行得更快。另一件需要考虑的事情是,也许不久前,您的数据库没有现在那么大,并且使用 dafult 内存分配(4 GB)就可以了。

您可以修改分配给 postgres 的内存并配置 flags,特别是work_memflag。我建议分配 2GB 额外内存并检查结果。如果您看到数据库再次使用 100% 的内存,请考虑增加整个内存和分配给数据库的内存。