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

使用的是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

体验地址:引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构

你可能感兴趣的:(数据库,数据分析)