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

不知道高版本的 mysql 里是否有了更简洁随机获取数据的解决方案?

  •  
  •   konakona ·
    54853315 · 2015-02-23 02:46:14 +08:00 · 2964 次点击
    这是一个创建于 3563 天前的主题,其中的信息可能已经有所发展或是发生改变。
    一直以来大概都是这样书写的:
    select ...from a left join b on a.id = b.id ....where ... and a.id >= (select FLOOR( MAX(id) * RAND()) FROM b) GROUP BY a.id ORDER BY a.id DESC LIMIT 5

    -,- 有些项目里需要随机获取的地方非常多,如果都这样写..实在是有些不够方便!

    想了解下现在的mysql可以更快速方便便捷高效的提取随机数据了吗?
    20 条回复    2015-02-25 00:45:58 +08:00
    vzch
        1
    vzch  
       2015-02-23 02:53:16 +08:00
    我觉得这不是 MySQL 的问题,这是子查询的效率问题
    konakona
        2
    konakona  
    OP
       2015-02-23 03:02:45 +08:00
    @vzch 你跑题了..
    xiaogui
        3
    xiaogui  
       2015-02-23 03:25:41 +08:00   ❤️ 1
    根据需求,重新审视各处随机获取信息的逻辑和设计,特殊情况下可以将随机逻辑放在数据库以外的地方处理。
    就本例来讲,可能正如 @vzch 所讲,是子查询的问题。
    konakona
        4
    konakona  
    OP
       2015-02-23 04:04:31 +08:00
    @xiaogui 我说的是..mysql3之前的round()的场景..你们为什么只看到我的子查询? TAT
    bombless
        5
    bombless  
       2015-02-23 05:26:29 +08:00
    明明是floor(逃
    xiaogui
        6
    xiaogui  
       2015-02-23 06:17:46 +08:00
    @konakona 你如何判断出是随机处“不高效”呢?
    msg7086
        7
    msg7086  
       2015-02-23 08:29:48 +08:00
    @xiaogui 因为ORDER BY RAND会扫全表。这是教科书式的错误写法了吧。
    否则也不会出现撸主这样硬生生用子查询来提高效率的写法了。
    xiaogui
        8
    xiaogui  
       2015-02-23 10:16:21 +08:00
    @msg7086 所以我也很搞不懂楼主要干嘛
    msg7086
        9
    msg7086  
       2015-02-23 10:19:29 +08:00
    @xiaogui 建议仔细反复阅读楼主的帖子。我觉得他说得挺明白了……
    jevonszmx
        10
    jevonszmx  
       2015-02-23 19:33:39 +08:00 via iPhone
    每次随机查,性能损失太大了,真心解决不了的话,不如加个字段rand_sort,写个定时脚本批量更新一下排序值。
    zhengkai
        11
    zhengkai  
       2015-02-23 20:17:30 +08:00
    小项目不需要关心子查询效率,大项目不会用子查询

    如果是范式你可以封装个函数,给定表名字段名,直接生成出 SQL

    我碰到这类问题会习惯的去想,比方说最近一万条的数组放进 memcache,然后现取现随机

    而且大部分场景,就算是随机,也会有根据时间调整展现几率的问题吧?
    konakona
        12
    konakona  
    OP
       2015-02-23 21:17:15 +08:00
    @xiaogui 我这么高端的sql都写出来了!标题那么闪烁!竟然还不知道我在问什么!呜呜呜呜!!!(why are you so diao!)


    @zhengkai 围绕“随机拿几条数据”这个point出发!哪怕只有1000条数据,如果只是随机拿出5条,用Round()方法的话,性能非常低,预计大约需要至多1秒。而如果用我的sql(经过子查询多次优化结果后的方法),至多需要0.001秒。

    所以,再小的项目也不能用Round(),因此在mysql3之后,已经取消了这个方法在ORDER BY中的使用(会报出Tips错误)。
    msg7086
        13
    msg7086  
       2015-02-23 21:49:52 +08:00 via iPhone
    RAND()…
    zhengkai
        14
    zhengkai  
       2015-02-23 23:43:20 +08:00
    @konakona 我说的不是 rand 用不用子查询,是说的用 rand(也就必然包含子查询或者 inner join)。按我的标准用 rand 的都是小项目,而不需要再在所有用 rand 的项目里区分大小了

    而且慢的原因是 mysql 没法自己优化,会把所有用不上的字段放在一起,所以 sort buffer 会非常大,极限情况就是表只有 id 这一个字段的时候不就不需要子查询了么。这个概念属于比较基础的知识,如果你是想说你这 SQL 很高端真不至于……这是老王2009年的blog http://hi.baidu.com/thinkinginlamp/item/1b9aaf09014acce0f45ba6d3 我在晚些时候知道是《高性能 MySQL》里说的

    另外那叫 rand 不是 round……看到你两个回帖都写的 round ……
    konakona
        15
    konakona  
    OP
       2015-02-24 01:00:27 +08:00
    @zhengkai 你们扯的可真远,麻烦你再回头看看我的标题和内容...我一直在围绕Round()的问题进行讨论,可是你们都在说子查询,外漏了,麻烦大家好好看帖..

    @msg7086 =.= 英文是因为我习惯了,我是团哥,有时根老外聊天,经常要打Round...
    iannil
        16
    iannil  
       2015-02-24 02:01:05 +08:00
    艾玛,刚撸了一遍那个31岁0基础好友买rmbp的帖子,这里显得好悠闲
    xuhai951753
        17
    xuhai951753  
       2015-02-24 17:26:03 +08:00
    konakona
        18
    konakona  
    OP
       2015-02-24 22:31:13 +08:00
    @xuhai951753 谢谢你还找了个帖子..不过请认真看我的帖子...=,=我的sql就是你找的帖子..
    xuhai951753
        19
    xuhai951753  
       2015-02-24 23:26:59 +08:00
    @konakona 帖子最下不是给了个更快的sql语句么。 [虽然没实测过。。 [光速逃
    konakona
        20
    konakona  
    OP
       2015-02-25 00:45:58 +08:00
    @xuhai951753 -,- 我这sql就是啊..但是我发这个帖子的最主要原因是想追问下目前的mysql有没有比较简单的办法?=,= 真的, 每次都这样写,我记不住..
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   6044 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 02:09 · PVG 10:09 · LAX 18:09 · JFK 21:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.