MySQL高性能优化规范建议总结
线上性能事故大多不是”数据库不行”,而是建表、索引、SQL、运维习惯里的一个个小坑叠加出来的。规范的价值在于把已知雷区前置到设计和评审阶段,比事后用慢日志救火便宜得多。下面按四组整理常用条款,每条附一句话原理,方便理解而不是死记。
表设计规范
- 统一使用 InnoDB 引擎:只有 InnoDB 同时提供事务、行级锁、MVCC 和崩溃恢复能力,MyISAM 的表级锁在并发写入下会成为瓶颈。
- 字符集统一 utf8mb4:utf8(三字节)存不下 emoji 和部分生僻字,混用字符集还会在 JOIN 时触发隐式转换、导致索引失效。
- 字段尽量 NOT NULL 并给默认值:NULL 会让索引统计、比较运算和存储都变得复杂(需要额外的 null 位图),优化器对 NULL 列的估算也更差。
- 主键短且单调递增:InnoDB 表按聚簇索引组织,主键会作为每个二级索引叶子节点的”书签”,主键越长所有索引越臃肿;随机主键(如 UUID)还会导致页分裂和写放大。
- 金额用 DECIMAL,不用 FLOAT/DOUBLE:浮点是近似表示,累加会丢精度,财务对账时对不上几分钱就是这么来的。
- 单表字段不宜过多,大字段垂直拆分:TEXT/BLOB 类大字段混在主表里会拉大行宽,降低缓冲池的有效缓存行数,拆到扩展表用主键关联即可。
- 控制单表数据量:行数越多 B+ 树越高、变更缓冲和统计信息越难维护;经验值是千万级以内保持单表,超出后优先考虑归档而不是直接上分库分表。
索引设计规范
- 为 WHERE、ORDER BY、JOIN、GROUP BY 涉及的列设计联合索引:索引的本质是用有序结构换取定位效率,查询条件不命中索引就只能全表扫描。
- 联合索引遵循最左前缀,列顺序按”等值在前、范围在后、区分度高的优先”:B+ 树按索引列的字典序排列,跳过一个前缀列就无法利用后续列的有序性。
- 高频查询优先做覆盖索引:SELECT 的列全部包含在索引里就不用回表,省掉一次按主键回聚簇索引的随机 IO。
- 单表索引控制在 5 个左右,定期清理冗余索引:每个索引都是一棵要维护的 B+ 树,写入时需要同步更新,索引过多直接拖慢 INSERT/UPDATE;冗余索引(如 (a) 和 (a,b) 中的前者)白占空间还增加优化器选错计划的概率。
- 禁止给每一列单独建索引:单列索引无法互相替代组合条件,MySQL 的 index merge 优化效果有限,远不如一个设计良好的联合索引。
- 避免在低区分度列上单独建索引:性别、布尔标志这类列过滤不掉多少数据,优化器算完成本往往还是走全表。
SQL 编写规范
- 禁止
SELECT *,只取需要的列:多取的列浪费网络 IO 和内存,还会让原本可以覆盖索引的查询被迫回表。 - WHERE 中不要对索引列做函数运算或隐式类型转换:
WHERE DATE(create_time)='...'或字符串列传数字,都会让索引列参与计算而无法走索引有序查找。 - 深分页改写为游标或延迟关联:
LIMIT 100000, 20要扫描并丢弃前十万行;先子查询定位主键再回表取数据,能利用覆盖索引把代价降到只扫 20 行:
SELECT o.* FROM orders o |
- 用 IN 代替同一列上的多个 OR,用 UNION ALL 代替无去重需求的 UNION:IN 可以走索引范围扫描,而 UNION 默认多一次去重排序。
- 避免大事务,批量写分批提交:事务越长持有的行锁和 undo 版本越久,锁冲突和 MVCC 读视图成本都会上升,还拉长主从延迟。
- 复杂计算挪到应用层:数据库的 CPU 是共享且昂贵的资源,排序、聚合能利用索引才划算,纯计算放应用层可以水平扩容。
运维操作规范
- 大表 DDL 用 gh-ost 或 pt-online-schema-change:原生
ALTER TABLE在旧版本会锁表或重建整表,影子表+增量同步方案把锁时间压到秒级。 - 批量变更超过百万行务必分批:单次大变更会造成主从延迟飙升、binlog 暴涨,分批还能在中途发现异常时及时止损。
- 禁止线上直接压测、禁止开发/测试环境连生产库:压测流量会挤占缓冲池和 IO,越权连接则是安全事故的常见入口。
- 应用账号遵循最小权限:只授予业务库的 SELECT/INSERT/UPDATE/DELETE,DDL 权限收敛到运维账号,误删表的爆炸半径会小得多。
- 监控不只看 QPS:慢查询数、锁等待、缓冲池命中率、复制延迟才是性能恶化的先行指标。
小结
- 表设计决定数据怎么存:InnoDB、utf8mb4、短主键、NOT NULL 是一组彼此配合的默认值。
- 索引设计决定数据怎么找:最左前缀、覆盖索引、控制数量是三条主线。
- SQL 编写决定索引能不能被用上:不对列做运算、避免深分页、拆小事务。
- 运维规范决定变更的爆炸半径:在线 DDL 工具、分批变更、最小权限。
- 把规范写进建表评审和 SQL Review 的 checklist,比依赖个人记忆可靠得多。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Dai Wei!
评论

