mysql查重处理问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/diaomeng11/article/details/52608518

碰巧今天需要对数据库中某个字段进行查重,并对重复的记录进行操作,于是上网查找了关于mysql数据库查重的语句,查了很多,给出的结果都是
SELECT j1.id FROM jokes j1 WHERE j1.content IN (SELECT content FROM jokes GROUP BY content HAVING COUNT(content) > 1)

这里content是jokes表中的一个非主键字段。

然而坑人的事情就这样发生,这条语句运行起来,简直慢的令人发指,全程没有耐心等待,这都查询不出结果,跟不用说修改和删除操作了。下面是这个语句查询的用时结果:

SELECT j1.id FROM jokes j1
 WHERE j1.content IN (SELECT content FROM jokes WHERE content !='' GROUP BY content HAVING COUNT(content) > 1)
执行:8 min 27 sec     总数:8 min 27 sec    630行

8分半,这是多久的时间啊,仅仅一条查询语句居然需要这么久的时间,可见效率是有多么的低。

于是我又想到了建立临时表的方法查询:

CREATE TABLE jokes_bak AS (
SELECT content FROM jokes GROUP BY content HAVING COUNT(content) > 1
)
建立临时表以后,进行查询:

SELECT id FROM jokes
 WHERE content IN (
SELECT content FROM jokes_bak)
执行:0.252 sec     总数:0.253 sec    630行
这个结果总算感觉正常了,那么接下来皆可以进行一系列的修改删除操作了,如: 修改操作:update jokes set content = 'chongfu' where content in ( SELECT content FROM jokes_bak)

共 630 行受到影响
执行耗时   : 1.545 sec
传送时间   : 0 sec
总耗时      : 1.546 sec

删除操作类似,其中,删除多余重复,留下id最小一条记录的操作为:

DELETE FROM jokes WHERE content IN 
(SELECT content FROM jokes_bak) AND id NOT IN 
(SELECT MIN(id) FROM jokes
 WHERE content IN (
SELECT content FROM jokes_bak) GROUP BY content)
通过搜索资料和尝试,发现还可以 使用inner join来查询,查询结果如下:

SELECT j1.id FROM jokes j1
INNER JOIN (SELECT content FROM jokes WHERE content !='' GROUP BY content HAVING COUNT(content) > 1) AS j2 USING(content)

执行:0.384 sec     总数:0.386 sec    630行

显然时间比第一种in的方式快的多,而事实上mysql中in、like应该尽量少用,第一种语句慢的另一个原因是因为没有建立索引。

那么这里还有另外一个问题,使用inner join的好处显而易见,不用额外建立一个临时表,但是进行修改删除操作的时候就出问题了,我使用一下语句进行修改:

UPDATE jokes SET SUBJECT = 'chongfu' WHERE id IN (
SELECT j1.id FROM jokes j1
INNER JOIN (SELECT content FROM jokes GROUP BY content HAVING COUNT(content) > 1) AS j2 USING(content))

提示错误:

错误代码: 1093

You can't specify target table 'jokes' for update in FROM clause

这个错误应该是mysql禁止对同一个表进行嵌套修改,防止一些错误的产生,这里解决这个问题的方法是,嵌套一层表查询,给表起个别名:

UPDATE jokes SET content='重复段子' WHERE id IN(
SELECT jd.id FROM(
SELECT j1.id FROM jokes j1
INNER JOIN (SELECT content FROM jokes GROUP BY content HAVING COUNT(content) > 1) AS j2 USING(content)
) jd)





猜你喜欢

转载自blog.csdn.net/diaomeng11/article/details/52608518