› MySQL 5.5 Community Server
› MySQL 5.6 Community Server
› Percona Configuration Wizard
› XtraBackup 搭建主从复制
Great Sites on MySQL
› Percona
› MySQL Performance Blog
› Severalnines
推荐管理工具
› Sequel Pro
› phpMyAdmin
推荐书目
› MySQL Cookbook
MySQL 相关项目
› MariaDB
› Drizzle
参考文档
› http://mysql-python.sourceforge.net/MySQLdb.html
soho176
V2EX  ›  MySQL

mysql 如何高效的 随机取数据?

  •  
  •   soho176 · Mar 24, 2013 · 6914 views
    This topic created in 4944 days ago, the information mentioned may be changed or developed.
    我想从文章列表里面随机取出固定数量的文章列表,现在的文章数量是200万,如何执行sql会高效/
    不想用order by rand。
    mysql对随机查询处理能力很差,遇到order by rand,就要全表扫描,性能非常差,容易给cpu耗死。
    13 replies  •  1970-01-01 08:00:00 +08:00
    lusin
        1
    lusin  
       Mar 24, 2013   ❤️ 1
    先随机取0-200w的一些数字,再按ID取数据会不会快?
    tysx
        2
    tysx  
       Mar 24, 2013
    如果ID是连续的就随即取几个范围内的数字,然后select in
    rqrq
        3
    rqrq  
       Mar 24, 2013
    网上遍地都是解决办法,有试过么?

    SELECT * FROM tbl AS t1
    INNER JOIN (
    SELECT ROUND(RAND() * ((
    SELECT MAX(id) FROM tbl
    ) - (
    SELECT MIN(id) FROM tbl
    )) + (
    SELECT MIN(id) FROM tbl
    )) AS id) AS t2
    WHERE t1.id >= t2.id ORDER BY t1.id
    LIMIT 1
    soho176
        4
    soho176  
    OP
       Mar 25, 2013
    id不是连续的,如果一个一个的取的话,那取的次数太多了,比如取10个随机文章就要查询数据库10次,效率有点低吧
    dementrock
        5
    dementrock  
       Mar 25, 2013
    dementrock
        6
    dementrock  
       Mar 25, 2013
    或者给每个post都assign一个连续的fake_id?时间长了如果post有删除的话可以定期更新这些fake_id 反正不会有其它用途
    min
        7
    min  
       Mar 25, 2013
    效率低不怕,预先半夜跑好几百份随机列表,要用的时候几百份里面取一份呗
    kisa77
        8
    kisa77  
       Mar 25, 2013   ❤️ 1
    分享一个以前用过的,1楼的方法如果主键非连续数字就不好使了

    select SQL_NO_CACHE cid,account,country,companyname

    FROM f_company as c

    JOIN (select ROUND(rand() * ((SELECT MAX( cid )

    FROM f_company))) as id) AS T

    where c.cid >= T.id limit 10

    当时是80万记录的f_company表(约780M)用时在0.006秒到0.016秒之间,可以接受
    soho176
        9
    soho176  
    OP
       Mar 25, 2013
    @min 几百份太少了,想让每个文章页面都放上随机文章10篇。
    soho176
        10
    soho176  
    OP
       Mar 25, 2013
    @rqrq 试过了几个都不理想,你的这个我刚试了 效率也低,随机取了10条,都用了0.05秒。
    soho176
        11
    soho176  
    OP
       Mar 25, 2013
    @kisa77 试了一下和2楼@rqrq 的效率差不多。
    risent
        12
    risent  
       Mar 26, 2013
    楼主这种每个页面都要显示随机数据的话,数据库处理起来估计很难高效,可以尝试下Solr里面的RandomSortField。
    napoleonu
        13
    napoleonu  
       Mar 27, 2013
    你有自增主键ID么?如果有的话:

    1.假设你每次需要随机50篇文章。
    2.让程序随机出100个不重复ID,之所以是100个是防止某些文章删除了,可根据情况调整。
    3.用select * from post where id in (2,3,5,7,11...) limit 50;取出文章。
    4.好了。即使你运气比较差,随机的100个ID里面有60篇文章被删除了,那就随他去吧,who care?

    如果没有自增ID,那么就调整业务加一个,不管是针对业务需求还是数据库性能优化都有好处,之后再使用上面的方案。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2873 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 52ms · UTC 03:28 · PVG 11:28 · LAX 20:28 · JFK 23:28
    ♥ Do have faith in what you're doing.