2017-08-10 46 views
0

我正在处理一个有许多事件获取数据的大型表。我想检查单个事件中的特定列(text或varchar)是否有重复项,并且每个行中都有重复出现的集列duplicity设置为1.由于目前表中有超过100000行,大约有30 000行属于该事件,因此子查询的任何连接都需要数分钟才能完成。MySQL高效地在大表中标记重复项

这是我到目前为止;它的工作原理,但仍需要几秒钟才能完成,我想学习更有效的解决方案。对于这个相对容易的任务来说,它感觉太笨重和丑陋。

DROP TEMPORARY TABLE IF EXISTS table2 
; 
CREATE TEMPORARY TABLE table2 AS (SELECT * FROM table WHERE ide = 123) 
; 
DROP TEMPORARY TABLE IF EXISTS table3 
; 
CREATE TEMPORARY TABLE table3 AS (SELECT id,odpoved FROM table 
    WHERE ide = 123 
    GROUP BY text_column 
    HAVING COUNT(*) > 1) 
; 
UPDATE (
    SELECT all.id id FROM table3 txt 
    INNER JOIN table2 all ON all.text_column = txt.text_column 
) a 
INNER JOIN table main ON main.id = a.id 
SET main.duplicity = 1 

目前这需要大约8秒钟,我预计事件中的数据量至少会增加三倍。

我无法修改现有的数据库或表结构。

我以前的方法 - 更好,但花了约4分钟就当前的数据集:

UPDATE table t1 
JOIN (
    SELECT id,text_column FROM table 
    WHERE ide = 123 
    GROUP BY text_column 
    HAVING COUNT(*) > 1) t2 
ON t1.text_column = t2.text_column 
SET t1.duplicity = 1 
+0

你多久会访问这个重复数据?如果不经常,您可以在实际查询进入时进行计算。无论如何,您的重复数据在任何时候都可能变得陈旧。 –

+0

我每天都会在数据导入后执行此操作;但是我不能让系统长时间卡住,因为它依赖于其他应用程序和用户。在系统高峰使用期间,我必须这样做。查询正在执行时,它会停止响应任何其他请求。 – LuH

+0

另外你的意思是数据变得陈旧? – LuH

回答

1

既然你不在乎你有多少重复的记录有,你可以使用exists与子查询找到重复的:

UPDATE table t1 
SET t1.duplicity = 1 
WHERE ide = 123 
    AND EXISTS (SELECT 1 FROM table t2 WHERE t1.text_column=t2.text_column and t1.id<>t2.id and ide=123) 

它还帮助,如果您有text_columnideid领域多列索引。

+0

这是不可行的 - 在我处理9分钟后杀死它的当前数据集。你可能在多列索引上,但不幸的是a)我不能改变表格,b)不同的事件把它们独特的数据放在不同的列上,所以我必须创建几对id-文本或id-ide-text的三元组,这可能会妨碍插入和更新性能。我只是在这里猜测。 – LuH

+0

我并不是在谈论一个唯一索引,而是一个可以加快查询速度的索引。 – Shadow

+0

我的意思是假设独特的数据,因为我正在检查重复数据。 – LuH