如何高效批量删除SQL数据_使用脚本分段删除降低压力
安全删除需分批、索引、游标分页WHERE条件字段必须有有效索引用id主键游标替代LIMIT单批1000~5000行并休眠避免fetchall全量加载。DELETE 语句不加 LIMIT 就直接崩库线上环境执行 DELETE FROM users WHERE status inactive 这种语句极大概率触发锁表、主从延迟、甚至 OOM。MySQL 默认事务下全表扫描逐行加锁生成大量 undo log不是删数据是给数据库做心肺复苏。真正安全的做法是分批、带索引条件、控制每批大小和间隔必须确保 WHERE 条件字段有有效索引比如 status 单独无索引但 (status, id) 联合索引可用用 id 或自增主键做游标分页比 LIMIT offset, size 更稳定避免 offset 越大越慢单批建议 1000~5000 行太小效率低太大锁时间长每批后 SLEEP(0.1) 或更久给复制和缓冲池喘息机会别信“先 SELECT 再 DELETE”——中间可能有新数据写入要用 SELECT ... FOR UPDATE 或原子性子查询兜底Python 脚本怎么安全跑完十万行删除用 mysql-connector-python 或 pymysql 写循环时最容易犯的错是把整个结果集一次性 fetchall() 到内存或者没关游标/连接脚本跑一半就报 MySQL Server has gone away。正确姿势是流式处理 显式事务控制每次只查一批待删 idSELECT id FROM logs WHERE created_at 拿到这批 id 后用 DELETE FROM logs WHERE id IN (1,2,3,...) 删除注意 IN 列表长度别超 max_allowed_packet每次删完立刻 conn.commit()不要攒事务出错时捕获 pymysql.err.IntegrityError 等并跳过异常 ID记录最后成功删除的 id 到临时文件或数据库断点续删才靠谱mysqldump truncate 不如直接用 pt-archiver有人想导出再清空或者用 TRUNCATE TABLE 图快——但 TRUNCATE 是 DDL会锁整表、重置 AUTO_INCREMENT、且无法加 WHERE 条件mysqldump --where 导出再删IO 和磁盘压力反而更大。 Cleanup.pictures 智能移除图片中的物体、文本、污迹、人物或任何不想要的东西