用 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 节省——这比调参实在得多。
