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 · 2710 次点击
    这是一个创建于 3567 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我需要给数据库里的所有成员(大约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?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5448 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 08:46 · PVG 16:46 · LAX 00:46 · JFK 03:46
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.