Shayon Mukherjee:通过降低 random_page_cost 在 Aurora Postgres 中实现查询速度提升 100 倍

Shayon Mukherjee:通过降低 random_page_cost 在 Aurora Postgres 中实现查询速度提升 100 倍

💡 原文英文,约900词,阅读约需3分钟。
📝

内容提要

Postgres 的 random_page_cost 默认值 4.0 基于机械硬盘,使优化器偏好顺序扫描而弃用复合部分索引,查询耗时约 11 秒;降至 1.1 后优化器改用索引,查询降至约 1.5 毫秒。建议谨慎调优,仅用于确认存在有效索引的查询,并可在 Rails 中按查询临时设置。

🔎

延伸解读

为何默认值导致索引失效

Postgres 的 random_page_cost 默认值 4.0 是基于机械硬盘的随机访问成本设定的。在 Aurora 等现代存储上,随机访问的实际成本远低于此,但优化器仍会高估索引扫描的代价,从而错误地选择顺序扫描或全索引扫描,放弃更高效的复合部分索引。这解释了案例中查询耗时 11 秒的原因。

调低参数后的性能逆转

将 random_page_cost 从 4.0 降至 1.1 后,优化器重新评估成本,转而使用复合部分索引,查询执行时间从约 11 秒骤降至 1.5 毫秒。这一变化并非索引本身改变,而是优化器决策被纠正,使索引得以发挥应有的加速作用。

按查询临时调整的实践

文章提供了一个 Rails 示例,通过 with_minimized_page_cost 方法在特定查询前临时设置 random_page_cost=1.1,执行后重置。这种方式避免全局修改参数,仅对确认存在有效索引的查询生效,降低了误用风险。

调优风险与适用边界

作者提醒,调低 random_page_cost 需谨慎,仅适用于你确定存在有效索引的查询。如果索引损坏或无效,降低该值可能让优化器选择更差的计划,反而拖慢查询。因此,应在充分验证索引状态后,再考虑针对性调整。

❓

Q&A

什么是 random_page_cost?它在 Postgres 中起什么作用?

random_page_cost 是 Postgres 中一个反映随机访问相对于顺序访问成本比值的参数。当该值较高时,Postgres 认为随机获取数据昂贵,倾向于顺序扫描;该值也会影响是否使用完整索引还是部分/复合索引。

为什么降低 random_page_cost 能大幅提升 Aurora Postgres 的查询速度?

Aurora Postgres 14.11 默认 random_page_cost 为 4.0,基于机械硬盘假设,导致优化器偏好顺序扫描而弃用复合部分索引。现代存储随机访问成本更低,降低该值(如 1.1)可让优化器改用索引,从而将查询从约 11 秒降至约 1.5 毫秒。

在 Aurora Postgres 中,调整 random_page_cost 前后查询计划有什么变化?

调整前(RPC=4.0),查询使用顺序扫描和全索引扫描,执行时间约 11 秒;调整后(RPC=1.1),优化器改用复合部分索引,执行时间降至约 1.5 毫秒。

如何在 Rails 应用中针对单个查询临时调整 random_page_cost?

可以在 Rails 中定义一个方法,在块内执行 SET random_page_cost=1.1,执行查询后确保 RESET random_page_cost。例如在 ApplicationRecord 中定义 with_minimized_page_cost 方法,并在需要时调用。

调整 random_page_cost 时需要注意哪些风险?

需要谨慎调优,仅对确认存在有效索引的查询进行调整。如果索引损坏或无效,降低 random_page_cost 可能导致性能更差。

Aurora Postgres 默认的 random_page_cost 是多少?作者对默认值有何建议?

Aurora Postgres 14.11 默认 random_page_cost 为 4.0。作者建议 Aurora 考虑将默认值降低到 1 到 2 之间,因为多次观察到降低默认值带来的好处。

🏷️

标签

➡️

继续阅读