DELETE WHERE 条件列无索引会导致全表扫描,使速度降至秒级甚至分钟级;应通过EXPLAIN确认执行计划、评估选择性与写负载,并避免函数导致索引失效,同时关注VACUUM或purge延迟对性能的影响。

DELETE WHERE 条件列没索引,速度直接掉到秒级甚至分钟级
MySQL 或 PostgreSQL 里执行 DELETE FROM table WHERE status = 'draft' 却卡住几秒甚至更久,大概率不是数据量大,而是 status 列没索引。数据库得全表扫描才能找出所有匹配行,每扫一行都可能触发锁、日志写入和事务开销。
实操建议:
- 先用
EXPLAIN DELETE FROM table WHERE status = 'draft'(MySQL)或EXPLAIN (ANALYZE) DELETE FROM table WHERE status = 'draft'(PostgreSQL)看是否走了type: ALL或Seq Scan—— 这就是全表扫描信号 - 确认该列选择性:如果
status只有 2–3 个值(如 'active'/'draft'/'deleted'),加单列索引效果有限;但若分布较散(比如订单状态含 10+ 种且常用某几种过滤),索引就值得建 - 建索引前评估写负载:高频写入表上频繁增删索引会影响
INSERT/UPDATE性能,尤其在小表或低频删除场景,别为一次优化引入持续开销
WHERE 条件含函数或表达式,索引会失效
写了 DELETE FROM logs WHERE DATE(created_at) = '2024-05-01',哪怕 created_at 有索引也白搭 —— MySQL 和 PostgreSQL 都无法用索引加速带函数的条件。
实操建议:
- 改用范围查询:把
DATE(created_at) = '2024-05-01'换成created_at >= '2024-05-01 00:00:00' AND created_at ,这样能走 <code>created_at索引 - 避免隐式类型转换:比如
WHERE user_id = '123'(user_id是INT),MySQL 可能放弃索引;统一用数字写法WHERE user_id = 123 - 复合条件注意顺序:如果经常查
WHERE category = 'A' AND is_deleted = 0,优先建(category, is_deleted)联合索引,而非两个单列索引
大表删数据别一口气删完,分批 + LIMIT 更稳
即使加了索引,一次性删百万行仍可能锁表、打满日志、拖慢主库复制 —— 尤其在 MySQL 的默认事务隔离级别下,DELETE 会锁住所有扫描到的记录(包括未命中行的间隙锁)。
实操建议:
- 用
DELETE FROM table WHERE status = 'draft' ORDER BY id LIMIT 1000分批删,每次只处理固定行数,配合循环脚本或定时任务 - 删完一批后加
SLEEP(0.1)(MySQL)或显式COMMIT(PostgreSQL),缓解主从延迟和锁竞争 - 避免用
OFFSET分页删(如LIMIT 1000 OFFSET 10000),越往后扫描越慢;改用基于主键/时间戳的游标式删除:WHERE id > 10000 AND status = 'draft' ORDER BY id LIMIT 1000
PostgreSQL 的 VACUUM 和 MySQL 的 purge 延迟影响真实性能
删完数据不等于磁盘立刻释放 —— PostgreSQL 需要后续 VACUUM 回收空间,MySQL InnoDB 的 undo log 和 purge 线程也可能滞后,导致后续查询仍慢或磁盘不降。
实操建议:
- PostgreSQL 删除大量数据后,尽快手动跑
VACUUM table_name(非VACUUM FULL,后者锁表);若常删旧数据,考虑启用autovacuum并调低autovacuum_vacuum_scale_factor - MySQL 5.7+ 查看
SHOW ENGINE INNODB STATUS中的PURGE DONE进度;如果History list length持续增长,说明 purge 跟不上,可临时调高innodb_purge_threads - 真正想缩表?PostgreSQL 用
VACUUM FULL或CLUSTER;MySQL 用OPTIMIZE TABLE(会锁表),生产环境务必避开高峰期
索引不是银弹,删得快的前提是:条件能走索引 + 扫描行数可控 + 事务和后台清理不拖后腿。最容易被忽略的是删完不检查 EXPLAIN 结果是否真变了,以及误以为“建了索引就万事大吉”,其实函数、类型、批量方式任何一个环节没对上,照样慢。










