上一篇
"小王最近接手了一个用户数据清理任务,需要删除3个月前注册但未消费且最后登录时间超过60天的'僵尸用户',他写了个简单的DELETE语句,结果跑了半小时还没结束,数据库CPU直接飙到90%...😱"
如果你也遇到过类似情况,这篇实战指南就是为你准备的!
-- 每次删除1000条,避免长事务 WHILE EXISTS ( SELECT 1 FROM users WHERE register_time < DATE_SUB(NOW(), INTERVAL 3 MONTH) AND last_login < DATE_SUB(NOW(), INTERVAL 60 DAY) AND total_consumption = 0 ) DO DELETE FROM users WHERE register_time < DATE_SUB(NOW(), INTERVAL 3 MONTH) AND last_login < DATE_SUB(NOW(), INTERVAL 60 DAY) AND total_consumption = 0 LIMIT 1000; COMMIT; -- 关键!每次提交释放锁 SLEEP 1; -- 给数据库喘息时间 END WHILE;
-- 先找出要删除的ID CREATE TEMPORARY TABLE to_delete AS SELECT id FROM users WHERE register_time < '2025-05-01' AND last_login < '2025-06-01' AND vip_level = 0; -- 通过主键快速删除 DELETE FROM users WHERE id IN (SELECT id FROM to_delete);
WITH targets AS ( SELECT id FROM products WHERE stock = 0 AND last_restock_date < DATE_SUB(NOW(), INTERVAL 1 YEAR) LIMIT 10000 ) DELETE FROM products WHERE id IN (SELECT id FROM targets);
-- 假设按月份分区 ALTER TABLE logs DROP PARTITION p_2024_01; -- 秒删整个分区!
-- 先标记要删除的数据 UPDATE large_table SET is_deleted = 1 WHERE create_time < '2024-01-01'; -- 业务低峰期再物理删除 DELETE FROM large_table WHERE is_deleted = 1 LIMIT 5000;
索引是王道:确保WHERE条件字段有复合索引
CREATE INDEX idx_cleanup ON users(register_time, last_login, total_consumption);
避开高峰期:在业务低峰期执行批量操作
监控进度:添加计数器查看执行情况
SELECT ROW_COUNT(); -- 查看上次操作影响行数
事务拆分:每1000-5000行提交一次
考虑归档:重要的数据先备份再删除
SET SESSION innodb_lock_wait_timeout = 120;
"处理海量数据删除就像吃大象——要一小口一小口来!" 🐘
记住三个关键点:
1️⃣ 分批处理是保命符
2️⃣ 索引优化是加速器
3️⃣ 低峰操作是明智之选
下次遇到要删除百万级数据时,试试这些方法,你会回来感谢我的!😉
(本文方法适用于MySQL/MariaDB,其他数据库需适当调整,最后测试时间:2025年8月)
本文由 俟宛亦 于2025-08-02发表在【云服务器提供商】,文中图片由(俟宛亦)上传,本平台仅提供信息存储服务;作者观点、意见不代表本站立场,如有侵权,请联系我们删除;若有图片侵权,请您准备原始证明材料和公证书后联系我方删除!
本文链接:https://vps.7tqx.com/wenda/516571.html
发表评论