PostgreSQL大表创建分区实战

目录

[1. 存储空间占用分析](#1. 存储空间占用分析)

索引大小估算公式:

具体案例计算:

[2. 风险分析与规避措施](#2. 风险分析与规避措施)

主要风险:

[3. 安全创建索引方案](#3. 安全创建索引方案)

步骤1:准备阶段

步骤2:分阶段并发创建索引

[4. 分区表特别优化](#4. 分区表特别优化)

方案A:仅索引热分区

方案B:使用部分索引

[5. 监控与应急措施](#5. 监控与应急措施)

实时监控命令:

应急终止:

[6. 存储优化技巧](#6. 存储优化技巧)

[7. 最终推荐方案](#7. 最终推荐方案)

性能影响对比


在 5 亿级数据量的分区表上创建索引需要谨慎操作,但不会导致数据库崩溃,只要合理规划资源和操作方式。以下是详细分析和安全操作指南:


1. 存储空间占用分析

索引大小估算公式:
复制代码
索引大小 ≈ 表行数 × (索引列大小 + 8字节) × 1.3
具体案例计算:
表名 行数 索引列 索引大小估算 实际大小范围
t_personnel_record 5亿 (plate, p_id) 5e8 × (20+8)×1.3 ≈ 18.2GB 15-25GB
t_cl_motor 5亿 (plate, ctime) 5e8 × (20+8)×1.3 ≈ 18.2GB 15-25GB

总索引空间:约 30-50GB(取决于实际数据分布)


2. 风险分析与规避措施

主要风险:
  1. 磁盘空间不足

    • 创建索引需要额外临时空间(≈ 索引大小的1.2倍)
    • 解决方案:确保磁盘空闲空间 > 最大表大小的1.5倍
  2. 长时锁表(默认CREATE INDEX)

    • 阻塞写操作,可能引发应用超时
    • 解决方案 :使用 CREATE INDEX CONCURRENTLY
  3. 内存/CPU过载

    • 排序操作消耗大量 work_mem
    • 解决方案:分阶段创建 + 资源控制

3. 安全创建索引方案

步骤1:准备阶段
复制代码
-- 检查磁盘空间(至少预留100GB)
SELECT pg_size_pretty(pg_tablespace_size('pg_default'));

-- 设置维护内存(加速创建)
SET maintenance_work_mem = '4GB';  -- 不超过总内存25%
步骤2:分阶段并发创建索引
复制代码
-- 对tr_personnel_record创建索引(不阻塞写入)
CREATE INDEX CONCURRENTLY idx_t_record_plate_pid 
ON t_personnel_record (plate, p_id);

-- 对t_clkk_motor创建索引(隔天执行)
CREATE INDEX CONCURRENTLY idx_cl_motor_plate 
ON t_cl_motor (plate);

耗时预估(基于 SSD 磁盘):

  • 单表索引创建:5亿行 ≈ 2-4小时
  • 并发模式速度降低30%,但保证业务连续性

4. 分区表特别优化

方案A:仅索引热分区
复制代码
-- 只为最近分区创建索引
CREATE INDEX idx_t_record_2025_plate ON t_personnel_record_2025 (plate);
CREATE INDEX idx_cl_motor_2025_plate ON t_cl_motor_2025 (plate);
方案B:使用部分索引
复制代码
-- 只索引非空数据(减少30%大小)
CREATE INDEX idx_tr_record_active 
ON t_personnel_record (plate) 
WHERE p_id IS NOT NULL;

5. 监控与应急措施

实时监控命令:
复制代码
-- 查看索引创建进度
SELECT 
  pid, 
  query,
  pg_size_pretty(pg_total_relation_size(relid)) AS size
FROM pg_stat_progress_create_index;

-- 监控锁等待
SELECT * FROM pg_locks WHERE mode = 'ShareUpdateExclusiveLock';
应急终止:
复制代码
-- 终止索引创建
SELECT pg_terminate_backend(pid) 
FROM pg_stat_activity 
WHERE query LIKE '%CREATE INDEX%';

6. 存储优化技巧

  1. 索引压缩

    复制代码
    CREATE INDEX ... WITH (compression = on);  -- PG 14+
    • 节省20-40%空间
  2. 表空间分离

    复制代码
    CREATE TABLESPACE index_ssd LOCATION '/ssd_data';
    CREATE INDEX ... TABLESPACE index_ssd;
  3. 清理旧索引

    复制代码
    DROP INDEX IF EXISTS old_index;  -- 创建前删除无用索引

7. 最终推荐方案

复制代码
# 操作流程
1. 申请维护窗口(业务低峰期)
2. 检查磁盘空间:确保 > 100GB 空闲
3. 设置参数:SET maintenance_work_mem='4GB';
4. 创建索引(并发模式):
   CREATE INDEX CONCURRENTLY ...;
5. 验证索引:
   \d+ t_personnel_record
6. 收集统计信息:
   ANALYZE t_personnel_record;

性能影响对比

场景 CPU峰值 磁盘IO 耗时 业务影响
并发创建索引 70% 4小时 只读延迟
标准创建索引 100% 极高 1.5小时 阻塞写入
不创建索引 - - - 查询超时

结论 :虽然大表索引会消耗资源,但合理操作不会导致崩溃。建议:

  1. 使用 CONCURRENTLY 模式
  2. 优先索引热分区
  3. 预留足够磁盘空间
  4. 在维护窗口操作

通过此方案,可在保证数据库稳定的前提下,为5亿级分区表安全创建索引。

相关推荐
清风6666663 小时前
基于单片机的水塔液位检测与智能调节报警系统设计
数据库·单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
gplitems1233 小时前
Technox – IT Solutions & Services WordPress Theme: A Practical
linux·服务器·数据库
不剪发的Tony老师4 小时前
MySQL 9.5创新版发布,有哪些新功能?
数据库·mysql
布朗克1684 小时前
MySQL 及 SQL 注入详细说明
数据库·sql·mysql·1024程序员节
武子康5 小时前
Java-154 深入浅出 MongoDB 用Java访问 MongoDB 数据库 从环境搭建到CRUD完整示例
java·数据库·分布式·sql·mongodb·性能优化·nosql
Austindatabases5 小时前
DBA 从“修电脑的” 到 上演一套 “数据治理” 大戏 --- 维护DBA生存空间,体现个体价值
数据库·dba
LB21125 小时前
Redis黑马点评 day01
数据库·redis·缓存
白小筠5 小时前
创建Django项目
数据库·django·sqlite
扑克中的黑桃A7 小时前
金仓多模数据库平替MongoDB的电子证照国产化实践——从2TB数据迁移到1600+并发支撑
数据库
计算机毕业设计小帅7 小时前
【2026计算机毕业设计】基于Django的社区婴幼儿预防接种系统
数据库·django·课程设计