记一次在一亿数据的大表里删除重复数据 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秒无结果的时候我都会停止运行。

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

相关推荐
从零开始的代码生活_9 分钟前
NAT、代理服务与内网穿透详解
linux·服务器·网络·c++·http·智能路由器
灯厂码农29 分钟前
C语言内存管理——内存对齐与共用体union
linux·服务器·c语言
GV191rLvq30 分钟前
基于Socket实现的最简单的Web服务器【ASP.NET原理分析】
服务器·前端·asp.net
运维管理1 小时前
H3C SecPath W2000-G[AK]系列Web应用防火墙 典型配置举例(E6711 E6712 E6713)-6W108-H3C 官方配置
服务器·网络·php
C+-C资深大佬2 小时前
python while循环
服务器·开发语言·python
Tian_Hang2 小时前
eclipse ditto 学习笔记
运维·服务器·开发语言·javascript·3d
江畔柳前堤2 小时前
第13章:docker生产环境部署实战
运维·git·docker·容器·代码复审
爱喝水的鱼丶2 小时前
SAP-ABAP:接口 vs 抽象类:ABAP OOP两类扩展方式的差异与选型原则
运维·性能优化·sap·abap·erp·经验交流
iCxhust2 小时前
linux目录是否保存在硬盘 启动后读入解析的
linux·运维·服务器
懒鸟一枚2 小时前
Linux 系统 Service 服务配置详解
linux·服务器·网络