可用磁盘 space 的减少是否是 `work_mem` 设置过低的良好总体指标?

is a reduction in free disk space a good overall indicator of a `work_mem` setting that is too low?

据我了解(经过大量在线搜索后)...

1- 如果查询的一个组件(排序、连接等)使用的 RAM/memory 多于我的 work_mem 设置 总内存服务器上所有当前操作使用的内存超出可用 OS 内存,查询将开始写入磁盘。

这是真的吗?

2- Postgres(和许多其他优秀的数据库引擎)使用内存来缓存很多,因此查询速度更快;因此,服务器 应该 指示可用内存不足,即使服务器并非真的 缺乏内存 也是如此。如此低的可用内存并不代表除了良好的数据库引擎和健康的利用率之外的任何东西。

这是真的吗?

3- 如果上面的 #1 和 #2 都成立,保持其他所有内容,如果我想要一个 work_mem 设置太低或总体不够的板指标 OS内存,我应该看看服务器可用磁盘 space 是否正在下降?

我的想法是否正确?

链接:

https://www.postgresql.org/docs/current/static/runtime-config-resource.html

http://patshaughnessy.net/2016/1/22/is-your-postgres-query-starved-for-memory

https://www.enterprisedb.com/monitor-cpu-and-memory-percentage-used-each-process-postgresqlppas-9

https://dba.stackexchange.com/questions/18484/tuning-postgresql-for-large-amounts-of-ram

我知道我可以设置 log_temp_files 并查看各个临时文件来调整 work_mem 设置,但我想要一个总体指标,我可以用它来确定是否 可能 work_mem 太低了,然后我开始四处寻找超过我的 work_mem 设置的临时文件大小。

我有 PostgreSQL 10。

处理查询需要几个步骤:

  1. 生成(所有)可能的计划
  2. 根据调整常量和统计数据估算这些计划的执行成本(在资源方面:磁盘 I/O、缓冲区、内存 CPU)。
  3. 根据调整常量选择 "optimal" 计划
  4. 执行选择的计划。

在大多数情况下,预计(第 2 步)比您的 work_mem 设置需要更多 work_mem 的计划不会在第 3 步中被选择。 (因为 "spilling to disk" 被认为非常昂贵) 一旦 step4 检测到它需要更多 work_mem,它唯一的选择就是溢出到磁盘。狗屎发生了......至少这不依赖于 OS 的页面交换过度使用的内存。)

规则很简单:

  • 散列连接通常是最优的,但会消耗内存
  • 不要尝试使用比你拥有的更多的内存
  • 如果预期(第 2 步)和观察到(第 4 步)内存之间存在差异,则您的统计数据有误。你将受到 spill-to-disk 的惩罚。
  • 缺少可用索引将导致散列连接或序列扫描。
  • 排序也使用 work_mem。机制类似:错误的估计会产生错误的计划。
  • CTE 已 often/allways(?) 实现。一旦您的缓冲区空间溢出,这将溢出到磁盘。
  • CTE 没有统计数据,也没有索引。

几个guidelines/advice:

  • 使用正确的数据模型(不要反规范化)
  • 使用正确的 PK/FK 和二级索引。
  • 运行 ANALYZE the_table_name; 在对 table 的结构或数据进行大量修改后收集新的统计数据。

监控:

  • 检查 Postgres 日志文件
  • 检查查询计划,比较观察到的 <--> 预期
  • 监控系统资源使用情况(在 Linux 上:通过 top/vmstat/iostat)