写点什么

10W 数据导入该如何与库中数据去重?

  • 2024-08-24
    福建
  • 本文字数:1027 字

    阅读完需:约 3 分钟

使用的是 PostgreSQL


在做大数据量(十万级)导入时,某些字段和数据库表里数据(千万级)重复的需要排除掉,把表数据查询出来用程序的方式判断去重效率很低,于是考虑用临时表。


  1. 先把新数据插入到临时表里,临时表结构和原始表一致。

  2. 用 SQL 的方式把不重复的数据 DataA 查询出来。

  3. 把 DataA 插入到原始表里。


因为不重复的数据我还要做一些其他的处理,所以查出来 DataA,若不需做特殊处理可直接使用 insert into select 的方式将第 2 步的数据插入到原始表,然后清空临时表


第 2 步有两种方式,一种是用 not exists 的方式,如


SELECT	* FROM	tableTemp t1 WHERE	NOT EXISTS ( SELECT 1 FROM tableName WHERE columnA = t1.columnA AND columnB = t1.columnB )
复制代码


第二种方式是用 left join


SELECT	* FROM	tableTemp t1	LEFT JOIN tableName t2 ON t2.columnA = t1.columnA AND t2.columnB = t2.columnB WHERE	t2.columnA IS NULL
复制代码


经测试(每个人的表结构和索引各有不同,我这里仅仅提供参考)


临时表数据量少时, not exists 用时较少,随着数据量越多用时越久。当数据达到 10w 时,用时 25s。

临时表数据量少时,left join 用时 30s,随着数据量越多变化不大,当数据达到 10w 时,用时 40s。


结论 1:单表去重时,只要导入的数据量不是特别特别大(20w 级以上),优先使用 not exists 做去重。

但还有一种情况,就是需要对两个表做去重。


例如


SELECT	* FROM	tableTemp t1 WHERE	NOT EXISTS ( 	SELECT 1 FROM tableNameA WHERE columnA = t1.columnA AND columnB = t1.columnB 	union all	select 1 from tableNameB WHERE columnA = t1.columnA AND columnB = t1.columnB 	);
SELECT * FROM tableTemp t1 LEFT JOIN tableNameA t2 ON t2.columnA = t1.columnA AND t2.columnB = t1.columnB LEFT JOIN tableNameB t3 ON t3.columnA = t1.columnA AND t3.columnB = t1.columnB WHERE t2.columnA IS NULL AND t3.columnA IS NULL
复制代码


这种情况下,临时表数据少时,not exists 用时较少,随着数据量越多用时越久。当数据达到 10w 时,用时 150s!!!。


临时表数据少时,left join 用时仍然是 30s,随着数据量越多用时越久。当数据达到 10w 时,用时仍然是 40s。


两者在数据量为 3w 时,用时不相上下


结论 2:双表去重时,当导入的数据在 3w 以下时,用 not exists,在 3w 以上时,用 left join。


文章转载自:救苦救难韩天尊

原文链接:https://www.cnblogs.com/GilbertDu/p/18363389

体验地址:http://www.jnpfsoft.com/?from=infoq

用户头像

还未添加个人签名 2023-06-19 加入

还未添加个人简介

评论

发布
暂无评论
10W数据导入该如何与库中数据去重?_数据库_不在线第一只蜗牛_InfoQ写作社区