Php MySQL删除重复的反向值

Php MySQL删除重复的反向值,php,mysql,myisam,duplicate-removal,Php,Mysql,Myisam,Duplicate Removal,我有MySQL MyISAM表: 表friendsid,friends\u id: 1,5 5,1 2,6 6,2 3,7 如何删除反向记录?如果记录值«1,5»存在值为«5,1»的记录,我需要删除«5,1» 谢谢你的帮助 DELETE FROM friends WHERE (id,friend_id) IN ( SELECT * FROM ( SELECT t1.id,t1.friend_id FROM friends t1 JOIN friends

我有MySQL MyISAM表:

表friendsid,friends\u id:

1,5

5,1

2,6

6,2

3,7

如何删除反向记录?如果记录值«1,5»存在值为«5,1»的记录,我需要删除«5,1»

谢谢你的帮助

DELETE FROM friends
WHERE (id,friend_id) IN
(   
   SELECT * FROM
   (
      SELECT t1.id,t1.friend_id
      FROM friends t1 JOIN friends t2
         ON t1.id=t2.friend_id AND t1.friend_id = t2.id
      WHERE t1.id > t1.friend_id
   ) t3
)
编辑

更好的语法是:

DELETE F1
FROM friends F1
  JOIN friends F2 ON F1.friend_id = F2.id AND F2.friend_id = F1.id
WHERE F1.id > F1.friend_id
但执行时间是一样的

此外,我还创建了一个快速而肮脏的基准测试

结果:

无索引:

Dalen: 600 => 400 rows. Time: 0.0274 Mark: 600 => 400 rows. Time: 0.4323 Frosty: 600 => 400 rows. Time: 0.4081 Nick: 600 => 400 rows. Time: 0.3201 id上的唯一索引,朋友id:

结论:

Dalen:列未编入索引时最快 Frosty:当列被索引时最快,标记正在关闭,在索引情况下甚至更快,而不考虑tmp表的创建时间。但是,当字段被索引时,tmp表创建所需的额外时间会增加 试试这个:

create temporary table tmp    
  select a.* from friends as a,friends as b 
  where a.id = b.friend_id 
    and a.friend_id = b.id    /* left out of original post */
    and a.id < b.id;

delete from friends using friends inner join tmp 
   on friends.id = tmp.id
  and friends.friend_id=tmp.friend_id;
如果friends表非常大,那么join比其他方法更有效


编辑:我修复了上面的create…select语句。经过测试,工作正常。对不起

对你来说都是+1。我想知道你的查询和Mark的查询之间是否有任何性能差异。我也很好奇,但现在必须上床睡觉了:我可能会在有时间的时候试着比较一下。事实上,这不是最快的解决方案,我做了一个116行的快速工作台,Frosty的解决方案使用0.017秒,而我的解决方案使用0.005秒,差别很小,它应该在大规模上进行测试。对不起,我没有测试你的代码,因为数据库的架构发生了变化,只执行了一次脚本。无论如何,Thanx稍后将测试所有代码。啊!查询现在已修复,请参见下面的。确定。谢谢你的反馈 Dalen: 600 => 400 rows. Time: 0.0274 Mark: 600 => 400 rows. Time: 0.4323 Frosty: 600 => 400 rows. Time: 0.4081 Nick: 600 => 400 rows. Time: 0.3201 Dalen: 600 => 400 rows. Time: 0.0201 Mark: 600 => 400 rows. Time: 0.0095 Frosty: 600 => 400 rows. Time: 0.0059 Nick: 600 => 400 rows. Time: 0.3257 Dalen: 600 => 400 rows. Time: 0.0168 Mark: 600 => 400 rows. Time: 0.0057 Frosty: 600 => 400 rows. Time: 0.0041 Nick: 600 => 400 rows. Time: 0.3209
create temporary table tmp    
  select a.* from friends as a,friends as b 
  where a.id = b.friend_id 
    and a.friend_id = b.id    /* left out of original post */
    and a.id < b.id;

delete from friends using friends inner join tmp 
   on friends.id = tmp.id
  and friends.friend_id=tmp.friend_id;