V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
l890908
V2EX  ›  程序员

mysql 如何将五百万数据的数据表重新随机排序?

  •  
  •   l890908 · 2018-03-03 10:55:06 +08:00 · 3893 次点击
    这是一个创建于 2460 天前的主题,其中的信息可能已经有所发展或是发生改变。
    想来想去没想到很高效的办法
    18 条回复    2018-03-04 02:06:10 +08:00
    wkan
        1
    wkan  
       2018-03-03 11:10:31 +08:00 via iPhone
    每一行插入一个随机数字,然后建索引排序
    lookas2001
        2
    lookas2001  
       2018-03-03 11:12:13 +08:00 via Android
    分配每一行一个随机 id 然后对随机 id 进行排序。
    O(n+nlogn)
    wqzjk393
        3
    wqzjk393  
       2018-03-03 11:13:30 +08:00 via iPhone
    我的笨办法就是新建一列,用随机函数给这列赋值,然后对这一列 order by
    willakira
        4
    willakira  
       2018-03-03 11:15:07 +08:00
    shuffle primary_id 即可
    feverzsj
        5
    feverzsj  
       2018-03-03 11:27:44 +08:00   ❤️ 1
    select 时不要 order by 就可以了,数据表本来就是无序的
    ipwx
        6
    ipwx  
       2018-03-03 11:41:16 +08:00 via iPhone
    @feverzsj 反对,你说的这种“随机”不满足均匀分布,会产生潜在的漏洞。
    l1093178
        7
    l1093178  
       2018-03-03 13:06:34 +08:00
    @feverzsj 这叫 natural order,不叫「随机」
    wd
        8
    wd  
       2018-03-03 13:08:37 +08:00 via iPhone
    order by ramdom()
    Zzde
        9
    Zzde  
       2018-03-03 13:13:23 +08:00 via iPhone
    @wd 这五百万数据随机起来 应该很慢的
    fiht
        10
    fiht  
       2018-03-03 13:33:22 +08:00
    order by random() 正解,不过不知道性能如何,之前自己用过,数据量不大的情况下是可以的。
    另:为啥会有这个需求?
    buliugu
        11
    buliugu  
       2018-03-03 14:04:19 +08:00
    shuffle primary_id 正解
    wwek
        12
    wwek  
       2018-03-03 14:09:17 +08:00
    @buliugu 正解
    dan2001go
        13
    dan2001go  
       2018-03-03 14:13:10 +08:00
    @fiht order by random() 的性能很低的。能不用就别用了。。
    shuffle primary_id 也不行吧,这么大的数据量,性能也不会好到哪里去。

    一种思路就是把所有的 primary_id,如果这些 id 是 1-2-3-4-5 …… 500W,这样连续的,自己用程序去 rand 出 30 个 id,select in()一下。不连续就生成一个连续的对应关系表。
    一般我在开发中都这么做的,当然我的数据也没到 500W 这个级别。

    知乎上有个文章,人家分析得更详细,可以参考一下。
    https://www.zhihu.com/question/20151242

    这个问题应该和你提的问题思路是一样的。
    l890908
        14
    l890908  
    OP
       2018-03-03 15:03:02 +08:00
    @wd
    @fiht

    order by rand 十万数据以下效率比较高,超过十万就不太好了,超过一百万效率更是极低
    slgz
        15
    slgz  
       2018-03-03 15:12:17 +08:00
    @fiht order by random() 这是什么操作,一般不都是 order by 字段名吗
    xpresslink
        16
    xpresslink  
       2018-03-03 16:34:36 +08:00
    首先来说,你这个做法应该不是目的。
    在数据库中无论你如何随机去生成另一个表,每行记录最终都会是有一个相对固定的自然存储顺序。
    一些重要的概念你要知道,random ()函数产生的伪随机数是不可以用于生产环境的抽奖之类的应用的。
    如果需要获取随机样本的情况,对随机性能要求不高,性能也不需要太高时,不用改原表。
    select * from table_name order by random() limit 5;
    或者从调用程序中实现。如果连续 pk,使用 random.sample 之类的。不连续先要把 pk 取出一个表,再 random.sample。
    pk 表可以维护在缓存里。
    starmoon1994
        17
    starmoon1994  
       2018-03-03 17:07:00 +08:00
    换个思路吧 把数据编号 1-500 万
    写一段随机数的代码 每次获取 1-500 万其中的一个数字
    jy01264313
        18
    jy01264313  
       2018-03-04 02:06:10 +08:00
    什么场景下解决什么问题,啥都没有就说效率?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5327 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 08:43 · PVG 16:43 · LAX 00:43 · JFK 03:43
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.