MySQL INSERT 语句耗时10秒问题排查指南
1. 基础信息收集
首先需要收集以下信息:
- 表结构(SHOW CREATE TABLE)
- 表数据量大小
- 服务器配置
- 当前数据库负载情况
- 具体的INSERT语句示例
2. 直接原因排查
2.1 检查锁等待
-- 查看当前锁等待情况
SHOW ENGINE INNODB STATUS;
-- 或使用performance_schema
SELECT * FROM performance_schema.events_waits_current;
2.2 检查慢查询日志
确保开启了慢查询日志并检查:
-- 查看慢查询配置
SHOW VARIABLES LIKE 'slow_query%';
SHOW VARIABLES LIKE 'long_query_time';
-- 临时设置(如需)
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 2; -- 设置为2秒
2.3 检查表状态
-- 查看表状态
SHOW TABLE STATUS LIKE 'your_table_name';
-- 查看索引状态
SHOW INDEX FROM your_table_name;
3. 深度排查方向
3.1 索引问题
- 检查是否有过多索引(每个INSERT需要更新所有索引)
- 检查是否有低效索引
3.2 触发器/外键约束
-- 检查触发器
SHOW TRIGGERS LIKE 'your_table_name';
-- 检查外键约束
SELECT * FROM information_schema.REFERENTIAL_CONSTRAINTS
WHERE TABLE_NAME = 'your_table_name';
3.3 自增锁问题
- 检查是否使用AUTO_INCREMENT且并发插入
- 考虑修改innodb_autoinc_lock_mode配置
3.4 硬件/配置问题
- 检查磁盘IO使用情况(iostat -x 1)
- 检查内存使用情况
- 检查innodb_buffer_pool_size配置是否合理
4. 优化建议
4.1 批量插入优化
将单条INSERT改为批量INSERT:
-- 替代多次单条插入
INSERT INTO your_table (col1, col2) VALUES
(v1, v2), (v3, v4), (v5, v6);
4.2 事务优化
适当增大事务批量提交量,但不要过大:
START TRANSACTION;
-- 多条INSERT语句
COMMIT;
4.3 表结构优化
- 考虑暂时禁用非关键索引(插入后再重建)
- 检查并优化BLOB/TEXT字段
4.4 参数调优
可能调整的参数:
-- 增大写缓冲区
SET GLOBAL innodb_buffer_pool_size = ?; -- 建议物理内存的50-70%
-- 调整日志相关参数
SET GLOBAL innodb_log_file_size = ?; -- 建议256M-2G
SET GLOBAL innodb_log_buffer_size = ?; -- 建议8M-64M
-- 调整flush方法
SET GLOBAL innodb_flush_method = O_DIRECT;
5. 监控方案
建立长期监控:
-- 开启performance_schema监控
UPDATE performance_schema.setup_instruments
SET ENABLED = 'YES', TIMED = 'YES'
WHERE NAME LIKE '%wait/io/file/%';
-- 定期收集性能数据
SELECT * FROM sys.schema_table_lock_waits;
6. 应急处理方案
当出现问题时可以:
- 使用
SHOW PROCESSLIST找出阻塞的会话 - 必要时终止问题会话:
KILL [process_id] - 考虑将写入操作转移到备库或临时表