V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
liu3734
V2EX  ›  数据库

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

  •  
  •   liu3734 · 2 天前 · 1604 次点击
    14 条回复    2025-10-18 15:37:00 +08:00
    GoogleQi
        1
    GoogleQi  
       2 天前
    数据多,性能差
    w568w
        2
    w568w  
       2 天前
    说明这人知识没更新过,不知道早在 SQL 2003 就已经有 TABLESAMPLE 子句了

    SQL Server:
    SELECT * FROM items TABLESAMPLE (1 ROWS);
    JiaZombie
        3
    JiaZombie  
       2 天前
    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
        4
    netnr  
       2 天前
    类似 C# EF 的 db.Users.ToList().Count
    Rickkkkkkk
        5
    Rickkkkkkk  
       2 天前   ❤️ 1
    @Livid 3 楼 ai
    Gilfoyle26
        6
    Gilfoyle26  
       2 天前
    好奇什么样的业务需要写这样的 sql
    GeruzoniAnsasu
        7
    GeruzoniAnsasu  
       2 天前
    有种前端分页的美
    zhengfan2016
        8
    zhengfan2016  
       1 天前
    @Gilfoyle26 背单词 app 从没背诵的单词行里随机抽一个,音乐 app 随机播放
    Ketteiron
        9
    Ketteiron  
       1 天前
    @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
        10
    newtype0092  
       1 天前
    @Ketteiron 现在真有这么干的么? 数据库资源这么宝贵,用来搞这种无关紧要的边角料业务逻辑有点浪费吧。。。
    moult
        11
    moult  
       1 天前
    看具体业务,比如 where 筛选后数据量很少很少的,用这个方式随机取一条还是方便高效的。
    Ketteiron
        12
    Ketteiron  
       1 天前
    @newtype0092 #10 `随机获得一条数据`这种需求,一般量级也就几千到一两万,调用频率不高就别管了。
    拿 mysql8 试了下,2w 条是 20 毫秒,如果用
    JOIN ( SELECT CEIL(RAND() * (SELECT MAX(id) FROM `xxx`)) AS rand_id )
    替代 rand() 可以快 20%左右
    不超过 5w 我是无所谓,这种奇葩需求一般也不会有大量数据。
    Livid
        13
    Livid  
    MOD
    PRO
       1 天前
    @Rickkkkkkk 谢谢,3 楼的账号已经被彻底 ban 。
    ethusdt
        14
    ethusdt  
       1 天前 via iPhone
    @zhengfan2016 这俩需求都可以让前端做吧,数据库尽量少做随机。
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   2479 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 11:09 · PVG 19:09 · LAX 04:09 · JFK 07:09
    ♥ Do have faith in what you're doing.