在大型数据库表中标记重复记录的最快方法

时间:2017-03-04 15:33:28

标签: php mysql

我正在寻找大数据问题的最佳解决方案。我已经考虑了一段时间,很高兴听到你的意见。

我有一个mysql数据库,其中包含一个包含大约5.000.000条记录的表,这些记录已加载并每日更改(新记录和更改的记录)。

该表中有一些重复的记录,我想每天都标记。

表格中有20列。我想找到在表的4列中具有相同数据的重复记录。

我发现重复项需要遍历每个重复记录以更新我的搜索功能并更新表中的记录,将其复制到另一个产品。

我希望尽可能少地使用mysql资源并尽可能快地编写脚本。

现在我有以下查询,但它确实很慢:

SELECT GROUP_CONCAT(id SEPARATOR '|') as ids,
       GROUP_CONCAT(stock SEPARATOR '|') as stock
FROM table
GROUP BY column1, column2, column3, column4
HAVING count(id) > 1;

我可以在for列上放置索引,但我认为运行此查询仍然会很慢。

我对你的愿景感到好奇。

1 个答案:

答案 0 :(得分:1)

听起来你想要这样的查询:

select col1, col2, col3, col4,
       group_concat(id separator '|') as ids,
       group_concat(stock separator '|') as stocks
from stock s
group by col1, col2, col3, col4
having count(*) > 1;

(这基本上就是你的查询。不过,这是我开始的地方。)

或者,获取每个重复的行可能会更快。您可以使用以下方法执行此操作:

select s.*
from stock s
where exists (select 1
              from stock s2
              where s2.col1 = s.col1 and s2.col2 = s.col2 and
                    s2.col3 = s.col3 and s2.col4 = s.col4 and
                    s2.id <> s.id
             );

为了让你有希望工作,你需要stock(col1, col2, col3, col4, id)的索引。此公式假设这些列中的值不是NULL

注意:如果速度更快但您仍需要原始格式,则可以将此条件置于group by查询中。

说实话,不过。我认为正确的方法是在四列上有一个唯一的索引:

create index unq_stock_col1_col2_col3_col4 on stock(col1, col2, col3, col4);

然后在updateinsert修改数据时处理重复的问题。最好在数据库中进行数据完整性检查,不要让数据问题失控。