一个困扰了很久的关于 MYSQL 排名算法的问题! - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
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
heat
V2EX    MySQL

一个困扰了很久的关于 MYSQL 排名算法的问题!

  •  
  •   heat 2015-03-20 18:06:46 +08:00 2993 次点击
    这是一个创建于 3932 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我需要给数据库里的所有成员(大约10万个)按照某个字段(point)做排名,这个排名既要显示在列表页,也要显示在会员详情页。

    于是我给每个会员做了一个排名缓存字段 rank

    我在前台有一个根据point倒序排列的页面(foreach $rs as $key=>$value),我的做法是在这个页面中判断缓存「rank字段」和「($key+1)+(当前页数-1)*每页显示数量」是否相等,如果不等就更新rank字段。

    这个方案解决了列表页面的排名同步到详情页的问题。但是新问题来了。用户的point是变化的

    我需要给point发生变化的个体更新他的排名(总不能到列表页去更新吧,尤其是用户排名比较靠后的),于是当用户的point发生变化的时候我又写了一个

    SELECT count(1) FROM user WHERE point>='用户当前最新的point值';

    并把这个 count(1) 写入到了该用户的rank字段,长久运行之后,总是发现 这个count(1) 和列表计算出的排名有差距,于是成员的排名总是发生浮动。。。体验很不好

    而我如果去掉列表页的更新方案,单独采用 SELECT count(1) 的话,又总是出现排名重复的情况(前几名都会有重复)

    请问大侠们有没有什么好的解决方案!?

    PS:

    SELECT count(1) FROM user WHERE point>='用户当前最新的point值';
    这段查询语句的效率也非常差,不知道有没有更好的写法
    3 条回复    2015-03-21 14:02:14 +08:00
    akira
        1
    akira  
       2015-03-20 23:59:21 +08:00
    如果你不需要实时,试试做成定时刷新 rank列表。这样逻辑上就非常简单粗暴了。
    1.读取所有用户的point,rank ,顺便order了
    2.从头到尾扫一遍,如果rank和位置不一致,存入更新列表
    3.更新变化了的rank入库
    jarlyyn
        2
    jarlyyn  
       2015-03-21 12:19:54 +08:00
    算法, sql优化不熟,没法给出意见。
    但个人觉得,性能的问题大部分情况下可以靠缓存来解决。
    那么我假设你的场景如下:
    1.top20的查看次数很频繁。
    2。大部分用户不是活跃用户。
    3。大部分用户的用户页很少被查看,被查看的多的是热门用户的排名。

    那么设置两个2缓存,在显示调用时调用,如果已经被删除的话则重新生成

    1。 top 20以及top20中最低的point.
    2.按用户缓存rank.

    再加入一个钩子程序,更新point时调用。
    1。如果原始point和新point大于top 20的最低point,则清除top 20的缓存
    2.清除对应用户的缓存。不要写入。
    liboyue
        3
    liboyue  
       2015-03-21 14:02:14 +08:00 via Android
    redis sorted set?
    div class="sep10">
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3683 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 00:51 PVG 08:51 LAX 16:51 JFK 19:51
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86