我们可能会经常遇到这种场景,一线的客户向业务投诉,说自己app的数据不对,然后业务就找到开发同学,各种排查,最后发现是因为程序处理不当的原因导致了脏数据,那遇到这类情况怎么办呢?最常见的处理方式,就是通过sql脚本去快速修复数据,然后再紧急通过热发布修复程序bug。
但是,我们如果遇到的是一张上千万甚至上亿级别的表出现了脏数据,如果sql没写好,很容易锁表,这将对业务会产生很大的影响。
例如我们有一张用户信息表t_user, 这个表有id,user_no, user_name, user_grade, user_points等字段,其中user_grade字段是索引
场景一. 假如我们要从t_user 中删除user_grade = 1的记录,很多人可能这样写修复SQL,如下所示:
delete from t_user where user_grade = 1; (不推荐,容易锁表,)
那有没有更好的办法呢?有,我们可以将上面的走user_grade索引,改为走id索引的删除语句
步骤如下:
1、转为select的delete语句
select CONCAT('delete from t_user where id=', id, "") as '删除sql' from t_user where user_grade = 1;
结果如下:
2、将第一步中的结果行(就是那些delete SQL语句)拷贝到一个空的SQL文件中
3、通知DBA在用户不活跃的时段执行上面的SQL,比如晚上11点以后,你会发现执行上面的SQL速度飞快,而且关键还不锁表。