【问题标题】:Mysql Deleting multiple random row from a tableMysql从表中删除多个随机行
【发布时间】:2012-01-26 10:32:04
【问题描述】:

我现在有一个有 604 000 行的表。我想删除 4000 个随机行,所以我的表将只包含 600 000 个条目。

有没有快速的方法?

非常感谢。

【问题讨论】:

  • DELETE FROM table WHERE id = RAND() LIMIT 4000? :) 或RANDOM()?也不确定;)

标签: php mysql


【解决方案1】:

理论上,这将是随机且快速的。实际上,它只会很快:

DELETE FROM tableX
LIMIT 4000

这将是随机的,但非常慢,有 600K 行:

DELETE FROM tableX
ORDER BY RAND() 
LIMIT 4000

这不会是真正随机的(因为 id 中通常存在间隙),它甚至可能不会完全删除 4000 行(但当有很多间隙时会减少一些),但它可能比以前更快。

需要在子查询中进行额外的包装,因为从多个表中删除的语法不允许LIMIT

DELETE td
FROM
      tableX AS td
  JOIN 
      ( SELECT t.id
        FROM
             tableX AS t 
          CROSS JOIN
              ( SELECT MAX(id) AS maxid 
                FROM tableX
              ) AS m
          JOIN
              ( SELECT RAND() AS rndm
                FROM tableX AS tr
                LIMIT 5000
              ) AS r
            ON 
               t.id = CEIL( rndm * maxid )
        LIMIT 4000
      ) AS x
      ON 
         x.id = td.id 

解释输出(来自 400K 行表的子查询):

id           table        possible_keys  key_len     rows 
 select_type         type             key     ref         Extra
1 PRIMARY <derived2> system                             1
1 PRIMARY <derived3> ALL                             5000
1 PRIMARY t          eq_ref PRIMARY PRIMARY 4 func      1 Using where;Using index
3 DERIVED tr         index          PRIMARY 4      398681 Using index
2 DERIVED                                            Select tables optimized away

【讨论】:

  • 请注意,它可能会删除少于 4000 行!
  • 我认为ORDER BY ROUND(RAND(), &lt;n&gt;) 会更快,n 越少越快。例如,n=2,n=3。显然它不会被打乱,但是当速度是一个问题时,这仍然有很大的帮助。
  • @FabienHaddadi 我看不出它在大桌子上有多快。如果表有 600k 行,它仍然需要对 600k 值进行排序。此外,您还向 ROUND() 函数添加了 600k 次调用;)
  • 因为它的种类较少。它创建具有较小数字的相似值组。我自己对苹果和香蕉的分类速度比 12 种蔬菜快。在性能方面进行检查。
  • 使用专门的排序算法,这种排序可能会更快。我认为引擎不可能知道这一点,或者有超过一两个通用算法可用于排序。但是测试它会很好。告诉我你发现了什么!
【解决方案2】:
delete from yourTable limit 4000

【讨论】:

  • 这是随机的。您无法确定将删除哪些行。
  • mysql不会按数据库中的本机顺序来做吗? (例如,前 4000 个最低 ID)
  • 可能是,但你不能依赖它。见这里stackoverflow.com/questions/8746519/…
  • 由于 MySQL 和 InnoDB 的怪癖,这可能会删除 MySQL 中的连续行。在其他 RDBMS 中机会较少。然而,“随机”并不是随机的足够。所以 -1 因为这很可能是可预测的
  • 我认为 OP 只是想删除一些行,无论如何。而这个查询正是这样做的。
【解决方案3】:

如果我不得不冒险猜测:

DELETE FROM table where id = (SELECT id FROM table ORDER BY rand() LIMIT 1) LIMIT 10

【讨论】:

    【解决方案4】:
    DELETE FROM TABLE ORDER BY RAND() LIMIT 4000;
    

    这需要时间……

    一种更快的执行方式(不是编写代码!)可能是在一个循环中进行 4000 次单独的删除

    DELETE FROM TABLE WHERE AssumedPKisInt = <ARandomNumber>
    

    当然,您需要确保不要尝试删除不存在或已删除的行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多