易君召
发布于 2026-08-05 / 作者:易君召 / 2 阅读
0

关系型数据库性能优化建议

优化分为:库表设计、索引优化、SQL 语句、配置参数、架构、运维、业务层规避几个层面,适用于 MySQL、PostgreSQL、openGauss 等主流关系库。

一、表结构设计优化

  1. 字段类型尽量小

    • 能用 TINYINT 不用 INT,能用 VARCHAR(n) 不用大文本;时间优先用 datetime/timestamp,不要存字符串时间。

    • 避免 NULL,尽量设置默认值,NULL 会增加索引、查询开销。

  2. 合理拆分大表

    • 单表数据量建议控制在千万级别以内(视硬件而定),超大表做水平分表(按时间、ID 哈希)、垂直分表(大字段拆分独立表)

  3. 主键设计

    • InnoDB 推荐自增主键,避免随机 UUID 做主键,防止页分裂、索引碎片。

  4. 避免过度宽表,大字段(text/blob)尽量拆分出去,减少内存 IO。

  5. 约束适度:外键会带来额外锁开销,高并发业务建议业务代码保证一致性,少用数据库外键。

二、索引优化(最核心)

  1. 索引不是越多越好

    • 索引加速查询,但降低 INSERT/UPDATE/DELETE 性能,每张表索引不宜过多。

  2. 联合索引遵循最左前缀原则

    sql

    -- 索引(a,b,c),where a=?、where a=? and b=? 可以命中;where b=? 无法命中
    CREATE INDEX idx_a_b_c ON t(a,b,c);
    
  3. 避免索引失效场景

    • 索引列做函数运算:where date(create_time)='2026‑08‑05' → 改为范围查询 create_time >= 'xxx' and create_time < 'xxx'

    • 隐式类型转换:字符串字段用数字查询,导致索引失效。

    • like '%关键词' 前缀通配符不走 B + 树索引,需要全文索引。

  4. 优先选择性高的列建索引,基数很低(性别、状态只有 2‑3 种值)建索引收益很小。

  5. 覆盖索引:查询字段全部包含在索引中,避免回表。

    sql

    -- 索引 idx(uid,name),select uid,name from t where uid=? 直接从索引返回,不访问数据页
    
  6. 定期分析索引碎片,大删改后执行统计信息更新,必要时 optimize/vacuum。

  7. 不要在低基数字段建立普通索引;排序、分组字段考虑加入联合索引。

三、SQL 语句优化

  1. 禁止 select *,只查需要的字段,减少网络传输与内存开销。

  2. 分页优化

    • limit 100000,10 会扫描前面十万行;优化:主键条件过滤 where id>100000 limit 10

  3. JOIN 优化

    • 小表驱动大表,join 字段必须建立索引;尽量减少 join 表数量,一般不超过 3 张。

    • 避免笛卡尔积,确认关联条件。

  4. in 集合不要过大,in 里面值成千上万时性能很差,改用 join 或者分批查询。

  5. 避免大事务

    • 事务尽量短小,大事务持有锁时间长,引发锁等待、回滚日志膨胀、主从延迟。

    • 批量更新拆成分批小事务。

  6. or 条件注意,or 两侧字段都要有索引,否则不走索引;可改写为 union all。

  7. 合理使用 explain 分析执行计划

    • 重点看:type(优先 range/ref,避免 ALL 全表扫描)、rows扫描行数、Extra(Using filesort、Using temporary 要尽量消除)。

四、数据库参数调优(以 InnoDB 为例)

  1. 内存

    • innodb_buffer_pool_size:最重要参数,服务器物理内存 50%‑70%,缓存数据页和索引页。

  2. IO 相关

    • innodb_flush_log_at_trx_commit:1 最安全;2 性能更高,丢失最多 1 秒数据,根据业务可靠性选择。

    • sync_binlog,高可用场景合理设置。

  3. 连接

    • max_connections不要盲目调很大,连接过多上下文切换开销大;配合连接池。

  4. 慢查询开启

    • 开启 slow_query_log,捕获慢 SQL,阈值一般 200ms,持续迭代优化。

  5. PostgreSQL /openGauss 重点:shared_buffers、work_mem、effective_cache_size、vacuum 策略。

五、业务与架构层面优化

  1. 读写分离

    • 查询走从库,写入走主库,分担压力;注意主从延迟对业务的影响。

  2. 引入缓存

    • Redis/Memcache 缓存热点数据,减少 DB 访问;做好缓存击穿、穿透、雪崩防护。

  3. 批量操作代替循环单条

    • 不要循环执行 insert;使用insert values(),(),()批量写入。

  4. 冷热数据分离

    • 历史归档数据迁移归档库,业务库只保留近期热数据。

  5. 分库分表

    • 数据量、QPS 极高时,中间件做分库分表(Sharding‑Sphere),解决单库容量与连接瓶颈。

六、锁与事务避坑

  1. 避免长事务,长事务会持有行锁,造成大量锁等待、死锁。

  2. 更新尽量按主键 / 索引条件,缩小锁定行数。

  3. 业务尽量按相同顺序更新多行记录,减少死锁概率。

  4. 隔离级别:一般业务用RC 读已提交,比 RR 可重复读减少很多间隙锁冲突。

七、运维监控

  1. 持续监控:QPS、TPS、慢查询、连接数、锁等待、回滚、缓冲池命中率。

  2. 定期更新统计信息,数据库根据统计信息生成执行计划,统计信息过时会导致选错索引。

  3. 定期清理大事务日志、碎片;备份策略不影响业务高峰 IO。

八、常见坑总结

  1. 索引建了但是没生效(函数、隐式转换、or、like 前缀)

  2. limit 大偏移量分页

  3. 超大 in 列表、多表无索引 join

  4. 大事务,批量操作不拆分

  5. buffer_pool 设置过小,大量磁盘 IO

  6. 盲目增加索引,写入性能急剧下降


原文链接 https://www.yijunzhao.cn/archives/relational-database-performance-optimization-tips

欢迎访问 小易撩挨踢

https://www.yijunzhao.cn/