所以我正在测试一个包含超过100万行数据的用户的大型数据库表,试图提出某种用户等级"但与使用这些数据的任何其他方式相比,它看起来非常慢,所以我想知道我是否采用了错误的方式。
我使用两列id
和points
拉取每一行数据,按点分组,因此具有相同点的人将具有相同的排名,然后按降序排序。
在这里,我做了一个快速的测试来测试它:
<?php
session_start();
$rank = 0;
$query = $conn->prepare("SELECT id, points FROM users GROUP BY points ORDER BY points DESC");
$query->execute();
foreach($query as $result){
$rank += 1;
if($result['id'] == $_SESSION['myid']){
echo '' . $_SESSION['myuser'] . ' is rank ' . number_format($rank) . ' globally.';
}
}
points
和id
已编入索引
这似乎加载得非常缓慢,而不是真的&#39;慢,但比我慢,所以我决定用它进行一些测试,并检查脚本使用以下方法执行多长时间:
<?php
$starttime = microtime(true);
session_start();
$rank = 0;
$query = $conn->prepare("SELECT id, points FROM users GROUP BY points ORDER BY points DESC");
$query->execute();
foreach($query as $result){
$rank += 1;
if($result['id'] == $_SESSION['myid']){
echo '' . $_SESSION['myuser'] . ' is rank ' . number_format($rank) . ' globally.';
}
}
$endtime = microtime(true);
$duration = $endtime - $starttime;
echo '<br /><br />This page took ' . $duration . ' seconds to load.';
根据1000次加载,平均加载时间为1.9468239237秒。
然后我在循环中添加了一个break;
,当它发现你的排名时,可能会缩短处理时间但无济于事。
所以我的问题是,你有更好的方法来计算这样的东西吗?
答案 0 :(得分:3)
http://sqlfiddle.com/#!9/05189/3
SELECT t.*
FROM users u
INNER JOIN (
SELECT id, points, IF(@rank IS NULL,@rank:=1,@rank:=@rank+1) rank
FROM users
ORDER BY points DESC) t
ON u.id = t.id
WHERE u.id = 3; # <- 3 is id you are looking for
答案 1 :(得分:1)
您可以尝试将查询更改为:
SELECT id, Name, 1+(SELECT count(*) from users u1 WHERE u1.Points > u1.Points) as Rank, Points
FROM users u WHERE u.id = your_id;
答案 2 :(得分:1)
我想尝试这样的事情
SELECT users.id, ranks.rank
FROM users
INNER JOIN (
SELECT points, ROW_NUMBER() AS rank
FROM users
GROUP BY points
ORDER BY points DESC
) ranks ON users.points = ranks.points
WHERE users.id = ?
使用您的用户身份准备查询的位置。
编辑:看来MySQL没有ROW_NUMBER()函数。这应该工作:
SELECT users.id, ranks.rank
FROM users
INNER JOIN (
SELECT t1.points, @rank := @rank + 1 AS rank
FROM (
SELECT points
FROM users
GROUP BY points
ORDER BY points DESC
) t1, (SELECT @rank := 0) t2
) ranks ON users.points = ranks.points
WHERE users.id = ?