2016-08-03 20 views
3

我有表所示:MySQL的复制场ID添加到当前场

id  IP  Subnet Duplicates Valid 
1  foo 16      1 
2  bar 24      1 
3  foo 28      1 
4  foo 32      1 

我想重复的行ID更新说明。是这样的:

id  IP Subnet Duplicates  Valid 
1  foo 16   3,4   0 
2  bar 24      1 
3  foo 28   1,4   0 
4  foo 32   1,3   0 

这里是我的查询:

update tblSample inner join (
      select 
      t1.Id, 
      group_concat(t2.Id) dups 
      from 
      tblSample t1 inner join tblSample t2 
      on t1.Id<>t2.Id) AND 
      ((t1.IP >> (32-LEAST(t1.Subnet,t2.Subnet)) 
       << (32-LEAST(t1.Subnet,t2.Subnet)) 
      = 
      ((t2.IP >> (32-LEAST(t1.Subnet,t2.Subnet)) 
       << 32-LEAST(t1.Subnet,t2.Subnet))) 
      group by 
      t1.Id 
     ) s on tblSample.Id = s.Id 
     set 
      Valid=0 ,Duplicates=dups 

我的代码工作,但它的速度很慢(约53秒10000记录)

我怎样才能提高速度? 有什么办法可以减少比较操作。

+0

这可能不是解决办法,但你可以使用EXPLAIN的声明MYSQL来跟踪你的查询是如何执行的。它应该帮助你建立更高效的查询连接.. – Archit

回答

1

这是一个在您的子查询中没有自连接的解决方案,可能不会大大提高性能,但尝试一下,并尝试解释它和您的问题。

update tblSample t1 
join (
    select name, group_concat(id order by id) as description 
    from tblSample 
    group by name 
) t2 
on t1.name = t2.name and cast(t1.id as char) <> t2.description 
set t1.description = replace(
         replace(
          replace(
          t2.description, 
          concat(',', t1.id, ','), 
          ',') 
          , concat(',', t1.id) 
          , '') 
         , concat(t1.id, ',') 
         , '') 
; 

Demo Here

+0

感谢您的回应。你的查询在简单比较中有更好的速度,但我的比较很复杂(检查重叠的IP网络)检查重叠,我必须做这个comarison:'(t1.IP >>(32-LEAST(t1.Subnet,t2.Subnet))< <(32-LEAST(t1.Subnet,t2.Subnet)))'=(t2.IP >>(32-LEAST(t1.Subnet,t2.Subnet))<<(32-LEAST(t1.Subnet,t2 .Subnet)))''这意味着我需要t1组字段 –

0

,你也可以使用这个查询测试:

UPDATE dupli d 
SET description = (
    SELECT CONCAT('duplicate in ',GROUP_CONCAT(`id` ORDER BY id)) 
    FROM (SELECT * FROM dupli) AS d1 
    WHERE `name` = d.`name` AND id <> d.id) ; 

样品

MariaDB [yourSchema]> UPDATE dupli d 
    -> SET description = (
    -> SELECT CONCAT('duplicate in ',GROUP_CONCAT(`id` ORDER BY id)) 
    -> FROM (SELECT * FROM dupli) AS d1 
    -> WHERE `name` = d.`name` AND id <> d.id) ; 
Query OK, 0 rows affected, 1 warning (0.00 sec) 
Rows matched: 4 Changed: 0 Warnings: 1 

MariaDB [yourSchema]> select * from dupli; 
+----+------+------------------+ 
| id | name | description  | 
+----+------+------------------+ 
| 1 | foo | duplicate in 3,4 | 
| 2 | bar | NULL    | 
| 3 | foo | duplicate in 1,4 | 
| 4 | foo | duplicate in 1,3 | 
+----+------+------------------+ 
4 rows in set (0.00 sec) 

MariaDB [yourSchema]> 
+0

tnx作为响应,如果你使用MariaDB,这个代码仍然有相同的问题 –

+0

你也可以使用EXPLAIN for UPDATE来查看哪些索引是错过的 –