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亿级分区表安全创建索引。

相关推荐
Asu52028 分钟前
思途SQL学习 0729
数据库·sql·学习
北亚数据恢复25 分钟前
服务器数据恢复—RAID上层部署的oracle数据库数据恢复案例
数据库·oracle·服务器数据恢复·北亚数据恢复
不辉放弃1 小时前
kafka的消息存储机制和查询机制
数据库·kafka·pyspark·大数据开发
ZZH1120KQ3 小时前
ORACLE的用户维护与权限操作
数据库·oracle
妮妮喔妮3 小时前
图片上传 el+node后端+数据库
javascript·数据库·vue.js
仰望星空的凡人8 小时前
【JS逆向基础】数据库之MongoDB
javascript·数据库·python·mongodb
duration~10 小时前
PostgreSQL并发控制
数据库·postgresql
给力学长10 小时前
自习室预约小程序的设计与实现
java·数据库·vue.js·elementui·小程序·uni-app·node.js
迷茫运维路11 小时前
MySQL5.7主从延迟高排查优化思路
数据库·主从延时高
菜鸟学Python12 小时前
Python web框架王者 Django 5.0发布:20周年了!
前端·数据库·python·django·sqlite