记一次在一亿数据的大表里删除重复数据 by 勤勤学长

场景

10月11日,某个用户出现了信息重复推送,导致出现重复数据,影响到了统计。

需要通过用户ID、时间戳、事件,找出相同msgid字段相同的数据,并删除。

已知,表有接近1亿条数据。

解决

查询重复数据

查看表索引,刚好有匹配的索引

sql 复制代码
 KEY `idx_storeid_event_ctime` (`store_id`,`event`,`ctime`),
sql 复制代码
SELECT
    msgid,
    COUNT(*) AS duplicate_count,
    min(id) as id
FROM
    `user_msg_list`
WHERE
    store_id = 233
    AND ctime > 1728615600
    AND ctime < 1728622800
    AND `event` = 'EventGroupChat'
GROUP BY
    msgid
HAVING
    COUNT(*) > 1;
# 查询的时候不要用 order by id desc
# 否则查询的时候,因为缺少id的索引,引起慢查询。
遍历删除

防止删除到其他的数据,所以还得把前边的条件一起放进来

sql 复制代码
DELETE 
FROM
	user_msg_list` 
WHERE
		store_id = 233
    AND ctime > 1728615600
    AND ctime < 1728622800
    AND `event` = 'EventGroupChat'
		AND id != 10086
		AND msgid !=318692996

项目上完整代码

我用的是thinkphp框架

php 复制代码
$where = "store_id = 233
            AND ctime > 1728615600
            AND ctime < 1728622800
            AND `event` = 'EventGroupChat'";

        $data = Db::table("user_msg_list")->where($where)->field("msgid,COUNT(*) AS duplicate_count,min(id) as id")->group("msgid")->having("COUNT(*) > 1")
            ->select()->toArray();

        foreach ($data as $v) {
            $id = $v['id'];
            $msgid = $v['msgid'];
            $msgIds = Db::table("user_msg_list")
                ->where($where)
                ->where("id!={$id}")
                ->where("msgid", $msgid)
                ->column("id");
            $res = Db::table("user_msg_list")->whereIn('id',$msgIds)->delete();
            dump($res);
        }

结束

数据太多了,动不动就是几秒都还无结果,3秒无结果的时候我都会停止运行。

防止出现缩表影响到正常业务的开展。

相关推荐
fengye20716111 分钟前
Windows 环境下硬核编译 CPython 避坑指南
windows
晴天的雨.99212 分钟前
【Linux】make & Makefile 核心知识点
linux·运维·服务器
不吃鱼的羊22 分钟前
如何建立高自尊
java·服务器·前端
丘山望岳24 分钟前
Linux基础指令入门篇
linux·运维·服务器
想做小南娘,发现自己是女生喵32 分钟前
LAN Device Monitor 第二周学习文档
java·服务器·数据库
hhhjhl42 分钟前
Zod 跨端三方库仓颉适配全流程
linux·运维·ubuntu
翔云12345643 分钟前
Gaea(小米MySQL Proxy)整体架构
运维·数据库·mysql
程序员清风1 小时前
LibreChat 实战:用 Docker 搭建可扩展的多模型对话平台
运维·docker·容器
志栋智能1 小时前
安全超自动化如何提升防御体系可靠性?
运维·安全·自动化
叼烟扛炮1 小时前
Linux 学习笔记(三十二):线程控制——创建、等待与分离
linux·运维·服务器·笔记·学习·1024程序员节