电商系统不能默认用myisam,因其表级锁、无事务、无崩溃恢复导致高并发写场景下卡死、数据不一致和丢数据;innodb才是首选,需合理配置buffer_pool_size、flush_log_at_trx_commit等参数,并按业务域垂直拆分、分离读写负载。

为什么电商系统不能默认用 MyISAM?
MyISAM 在早期 MySQL 电商项目中很常见,因为它读快、索引轻量,但它的表级锁在订单创建、库存扣减这种高频写场景下会直接卡死。用户点“立即购买”后页面转圈,后台查 SHOW PROCESSLIST 会看到一堆 Waiting for table level lock。这不是并发不够,是引擎选错了。
- MyISAM 不支持事务,一次库存更新失败(比如网络中断),
UPDATE stock SET qty = qty - 1 WHERE sku = 'A001'执行一半就断了,数据直接不一致 - 没有行级锁,哪怕只改一条订单状态,整张
orders表都会被锁住,其他用户下单全排队 - 崩溃恢复能力弱,服务器意外重启后可能丢数据,电商核心表绝不能赌这个概率
InnoDB 是电商首选,但要注意这些配置项
InnoDB 能扛住高并发写,前提是它没被默认配置拖累。很多团队直接装完 MySQL 就上线,结果发现 INSERT 变慢、主从延迟飙升,其实问题出在几个关键参数上。
-
innodb_buffer_pool_size必须设为物理内存的 70%–80%,否则热点商品页频繁刷盘,性能断崖下跌 -
innodb_flush_log_at_trx_commit = 1是安全底线,别为了“提速”改成 2 或 0——电商要的是账务准确,不是每秒多写 100 条日志 -
innodb_file_per_table = ON必开,否则所有表挤在一个ibdata1文件里,删掉一张大日志表都释放不了磁盘空间 - 主键必须是自增
BIGINT,别用 UUID 或字符串做主键——二级索引体积暴增,订单表一亿行时查询慢 3 倍不止
什么时候该考虑分库分表?别等 SELECT COUNT(*) FROM orders 跑 20 秒才动手
单库 InnoDB 能稳撑到千万级订单,但有两个信号出现时,就得启动拆分:一是主从延迟持续 > 5 秒,二是慢查询日志里反复出现 Using temporary; Using filesort 的聚合分析语句。
- 优先按业务域垂直拆分:
user_db、order_db、product_db,比盲目水平切分更可控 - 水平分片别早于 5000 万行订单,过早引入 ShardingSphere 或 MyCat 会把简单问题复杂化
- 所有跨库 JOIN 改成应用层两次查询,数据库不负责拼数据——这是电商系统最常踩的“想当然”坑
读多写少的报表类查询,别硬扛在主库上
运营每天跑的“昨日各品类 GMV 排行”,本质是扫描数百万订单 + 关联商品分类 + 按天聚合,这类查询会吃光主库 IO,影响实时下单。它不该和交易链路共用同一套实例。
- 建专用从库,设置
read_only = ON并关闭binlog,避免误操作和日志开销 - 对报表表加
WHERE create_time >= '2026-03-16'这种确定性分区条件,让优化器能跳过历史分区 - 如果报表逻辑太重(比如要关联用户画像宽表),宁可导出 CSV 到 ClickHouse 做分析,也别在 MySQL 里硬写
GROUP BY套嵌套子查询
电商系统最易被忽略的点,其实是“写操作的原子粒度”。一个下单请求背后涉及库存扣减、优惠券核销、积分变动、物流单生成,这些不能靠应用层 try-catch 拼成事务,得靠数据库层真正支持的分布式事务方案(如 Seata + XA)或最终一致性补偿,否则凌晨三点告警邮件里的“超卖 127 件 iPhone”就真不是段子。











