主要观点:近期遇到规划器选择错误计划的情况,以 PostgreSQL 14 数据库为例,某网站查询因语句超时 3 分钟被终止,主库查询毫秒级返回,副本库 3 分钟后被终止,经分析主库使用 index\_active\_voluntaries 索引,副本库基于 cached\_due\_date 顺序扫描数据,导致大量数据随机读取,提出两种解决方法,一是使用 MATERIALIZED 子句强制选择所需索引,二是添加专门索引,添加新索引后查询性能大幅提升,同时探讨了副本库选择错误索引的原因但未确定。
关键信息:
- 问题查询:SELECT max(voluntaries.cached_due_date) FROM changes51_gauge_8273.voluntaries WHERE voluntaries.mutilation_id = 12122656 AND voluntaries.workflow_state <> 'deleted';
- 主库索引:index\_active\_voluntaries
- 副本库问题:基于 cached\_due_date 顺序扫描大量数据
- 解决方法:使用 MATERIALIZED 子句或添加专门索引 depesz\_bandaid
- 新索引效果:查询性能大幅提升
- 副本库配置:64 核 512GB 内存,effective_cache_size 248.8GB,shared_buffers 124.4GB;主库 48 核 392GB 内存,effective_cache_size 185.6GB,shared_buffers 93.3GB
重要细节: - 表数据量:232GB 数据,2GB toast,380GB 索引,共 50 列不同数据类型,30 个索引
- 索引信息:index\_active\_voluntaries( mutilation_id, workman_exhale_id) WHERE workflow_state::text <> 'deleted'::text 等
- 不同查询执行计划及耗时:原查询在主库和副本库的情况,使用 MATERIALIZED 子句和新索引后的查询计划及耗时
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。