MySQL 5.6+已移除INSERT DELAYED,应改用批量插入(100–500行/批)+显式事务;日志表可选MyISAM或ROCKSDB(纯写场景),但需规避查询阻塞;分表比分区更有效,字段类型最小化可显著降低I/O。

用 INSERT DELAYED 还是直接放弃?
MySQL 5.6 及以后版本已彻底移除 INSERT DELAYED,强行使用会报错 ERROR 1064 (42000)。它原本只适用于 MyISAM 表,且在高并发下实际延迟不可控、丢失风险高,现在连语法都不支持了。别查旧教程,直接跳过。
日志表必须用 ENGINE=InnoDB 吗?
不一定。如果日志表只写不读、不依赖事务、不需崩溃恢复,ENGINE=MyISAM 或更优的 ENGINE=ROCKSDB(需启用 MyRocks)反而吞吐更高。但注意:MyISAM 写入时整表锁,若混杂 SELECT 查询会严重阻塞;而 InnoDB 的行锁 + 插入缓冲(innodb_change_buffer)对主键/索引外的写入更友好。
- 纯追加写 + 零查询 →
MyISAM(简单场景可测)或ROCKSDB - 有定时归档/查询需求 →
InnoDB,关掉非必要索引(尤其是TEXT字段上的全文索引) - 务必禁用
innodb_flush_log_at_trx_commit=2(牺牲最多 1 秒数据持久性换性能),并调大innodb_log_file_size
INSERT ... VALUES (),(),() 批量写比单条快多少?
实测 100 条批量写入比 100 次单条快 5–15 倍,取决于网络往返和事务开销。但别盲目堆到 10000 条:MySQL 默认 max_allowed_packet 通常为 4MB,超限会报 ERROR 1153 (08S01): Got a packet bigger than 'max_allowed_packet' bytes。
INSERT INTO log_table (ts, level, msg) VALUES (NOW(), 'INFO', 'user login'), (NOW(), 'WARN', 'slow query detected'), (NOW(), 'ERROR', 'db timeout');
- 每批控制在 100–500 行(视单行大小调整)
- 显式开启事务:
BEGIN; INSERT ...; COMMIT;,避免自动提交开销 - 应用层做缓冲:内存队列积攒 N 条再刷库,比数据库层优化更可控
分区表能扛住每秒上千写入吗?
按时间分区(如 PARTITION BY RANGE (TO_DAYS(ts)))对写入性能几乎无提升,反而增加优化器负担;但对后续按月归档、DROP PARTITION 清理极有用。真正起效的是「分表」——比如按天生成 log_20240501、log_20240502,用应用路由写入,彻底规避锁争用和 B+ 树分裂压力。
- 不要用 MySQL 自动分区应对高写,那是给查询设计的
- 分表后每个表独立
auto_increment、独立缓冲池,写入完全隔离 - 务必在应用层维护表名映射,避免跨表查询(日志本来就不该频繁跨天查)
TINYINT 存 level 而不是 VARCHAR(10),用 INT UNSIGNED 存 user_id 而非 BIGINT,单行省 10 字节,每秒 2000 写入就是 20KB/s 的 I/O 节省——这比调参实在得多。










