liu3734
V2EX  ›  数据库

怎么评价 order by rand() limit 1 这条 sql

  •  
  •   liu3734 · Oct 17, 2025 · 3870 views
    This topic created in 388 days ago, the information mentioned may be changed or developed.
    15 replies  •  2025-10-21 11:15:47 +08:00
    GoogleQi
    GoogleQi
    Oct 17, 2025
    1
    数据多,性能差
    w568w
    w568w
    Oct 17, 2025
    2
    说明这人知识没更新过,不知道早在 SQL 2003 就已经有 TABLESAMPLE 子句了

    SQL Server:
    SELECT * FROM items TABLESAMPLE (1 ROWS);
    JiaZombie
    JiaZombie
    Oct 17, 2025
    3
    SQL 语句分析:ORDER BY RAND() LIMIT 1
    优点
    随机性: 使用 ORDER BY RAND() 可以从结果集中随机选出一条记录,非常适合需要随机抽样的场景。
    简单易用: 语法简单,易于理解和应用,直接满足随机取数的需求。
    缺点
    缺点 描述
    性能问题 当数据表非常大时,ORDER BY RAND() 可能会导致全表扫描,从而影响性能。
    不适合高频请求 在高频请求中,使用这种方法可能会导致数据库性能下降,尤其是在并发量大的情况下。
    可扩展性差 随着数据量的增长,这种方法的效率将显著降低,不适合用于大规模应用。
    更优替代方案
    使用随机数列: 在某些情况下,可以考虑在表中添加一个随机数列,然后通过随机数值来进行选择,具体操作示例如下:
    `SELECT * FROM your_table WHERE random_value >= RAND() ORDER BY random_value LIMIT 1;`
    使用其他随机选取方法: 例如,可以先通过 SELECT COUNT(*) 获取总行数,再利用随机数选择特定行。
    这种方式在性能上通常要优于 ORDER BY RAND(),尤其是表数据量大的情况下。

    总结
    总的来说,ORDER BY RAND() LIMIT 1 是一种简单有效的随机选取方法,但在应用于大量数据时应谨慎使用,需考虑其性能和可扩展性。针对具体应用场景,选择合适的随机选取方法是更好的实践。
    netnr
    netnr
    Oct 17, 2025
    4
    类似 C# EF 的 db.Users.ToList().Count
    Rickkkkkkk
    Rickkkkkkk
    Oct 17, 2025❤️1
    5
    @Livid 3 楼 ai
    Gilfoyle26
    Gilfoyle26
    Oct 17, 2025
    6
    好奇什么样的业务需要写这样的 sql
    GeruzoniAnsasu
    GeruzoniAnsasu
    Oct 17, 2025
    7
    有种前端分页的美
    zhengfan2016
    zhengfan2016
    Oct 17, 2025
    8
    @Gilfoyle26 背单词 app 从没背诵的单词行里随机抽一个,音乐 app 随机播放
    Ketteiron
    Ketteiron
    Oct 17, 2025
    9
    @Gilfoyle26 #6 获取一条随机数据是很正常的需求,例如随机点一首歌,随机找一位幸运观众 (假设不想使用任何手段的缓存)。

    ------
    其实 rand() 的 O(n*log(n)) 开销在部分场景还是能承受的
    换聚簇索引或者抽样可以快一点:
    https://stackoverflow.com/questions/40273291/sql-select-a-random-row-in-o1-time
    https://stackoverflow.com/questions/60019318/sql-command-to-include-a-random-row-from-the-table
    如果 ID 连续还可以通过两次请求实现 O(1), 但额外请求开销值不值就另说了。
    newtype0092
    newtype0092
    Oct 17, 2025
    10
    @Ketteiron 现在真有这么干的么? 数据库资源这么宝贵,用来搞这种无关紧要的边角料业务逻辑有点浪费吧。。。
    moult
    moult
    Oct 17, 2025
    11
    看具体业务,比如 where 筛选后数据量很少很少的,用这个方式随机取一条还是方便高效的。
    Ketteiron
    Ketteiron
    Oct 18, 2025
    12
    @newtype0092 #10 `随机获得一条数据`这种需求,一般量级也就几千到一两万,调用频率不高就别管了。
    拿 mysql8 试了下,2w 条是 20 毫秒,如果用
    JOIN ( SELECT CEIL(RAND() * (SELECT MAX(id) FROM `xxx`)) AS rand_id )
    替代 rand() 可以快 20%左右
    不超过 5w 我是无所谓,这种奇葩需求一般也不会有大量数据。
    Livid
    Livid
    MOD
    PRO
    Oct 18, 2025
    13
    @Rickkkkkkk 谢谢,3 楼的账号已经被彻底 ban 。
    ethusdt
    ethusdt
    Oct 18, 2025 via iPhone
    14
    @zhengfan2016 这俩需求都可以让前端做吧,数据库尽量少做随机。
    liu3734
    liu3734
    OP
    Oct 21, 2025
    15
    相比较而言,如果我先查 count(*),计算一个小于 count(*)的随机正整数 n 然后 where id > n limit 1, 这样也可以随机取到一个记录。随机性下降了,因为 id 可能并不连续,那么跳完后的 id 被取到的概率会变大。但是性能上升了。有什么随机取一条记录的办法吗?
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   953 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 39ms · UTC 20:15 · PVG 04:15 · LAX 12:15 · JFK 15:15
    ♥ Do have faith in what you're doing.