3

在我的 MySQL 数据库中,我有一个包含超过 1000 万行的表 (PERSONS),两个重要的列是:

  • ID
  • 积分

我想知道 ID = randomid的人的等级

我想将他的“等级”归还给这个人,这取决于他的积分。他的排名不会是确切的行号,而更像是一个百分比层。比如:“你在前 5%”或“你在 10% - 15% 的层中”。

当然,我可以通过将行数除以总行数来查询表并将行号转换为层%。但我的问题是,用 LIMIT X, 1 抓取几行是否会更快(有 10M+ 行),其中 X 将是表格百分比 100、95、90、85 .. 上的一行。下一步:检查该行的点数是否低于当前人的点数,如果是,则抓取下一层%行,如果不是,则返回上一层行。

在 person 表中有 9 列,其中包含 2 个 bigint、4 个 varchars 150、1 个日期和 2 个布尔值。

当然,我更愿意获得确切的行排名,但根据我的测试,这很慢,至少需要几秒钟,而我的 wat 可以在几百秒内完成。

另外,我建议的方式在有几个层具有相同点时是不精确的,但它不需要那么精确,所以我们可以忽略这个事实。

额外的信息,我用 PHP 编程,所以如果在 PHP + MySQL 中有一个特定的解决方案,那也很好。

最后,值得一提的是,该表以每小时 20k 行的速度增长(几乎每天 500k)。

我感谢所有的帮助。

4

1 回答 1

0

你可以试试这个。我首先计算具有更多点的行数,然后将其加一,以防有许多行具有相同的点数。因此,如果有 10 行具有相同的点数,则它们的排名都与该组中的第一行相同。

SELECT SUM(CASE WHEN points > (SELECT POINTS FROM YOUR_TABLE WHERE ID = randomid) THEN 1 ELSE 0 END) + 1 as Rank,
       (SUM(CASE WHEN points > (SELECT POINTS FROM YOUR_TABLE WHERE ID = randomid) THEN 1 ELSE 0 END) + 1) / COUNT(*) as Pct
FROM   YOUR_TABLE

如果这很慢,我会运行两个查询。首先获取该 ID 的积分,然后将其插入第二个查询以确定排名/pct。

SELECT POINTS 
FROM   YOUR_TABLE
WHERE  ID = randomid

然后计算等级和 pct,从上面插入点。

SELECT SUM(CASE WHEN points > POINTS THEN 1 ELSE 0 END) + 1 as Rank,
       (SUM(CASE WHEN points > POINTS THEN 1 ELSE 0 END) + 1) / COUNT(*) as Pct
FROM   YOUR_TABLE
于 2013-05-20T15:50:22.590 回答