[英]How i can optimize my ranking query in mysql?
Multiple records are being saved for each date against each subscription id.针对每个订阅 ID 为每个日期保存多条记录。 There is coins column, All subscriber gets few coins.
有硬币栏,所有订阅者获得的硬币很少。 It is basically a rewarding system.
它基本上是一个奖励系统。 I want to get the rank of current subscriber.
我想获得当前订阅者的排名。 There are 2 tables that are being used.
有 2 个表正在使用。
For example if user has earned total of 1000 coins, it remains 1000 in user reward table, and if he has used 200 coins somewhere, i add an entry in coins history table.例如,如果用户总共赚了 1000 个硬币,它在用户奖励表中仍然是 1000,如果他在某处使用了 200 个硬币,我在硬币历史表中添加一个条目。 So currently he has 800 coins left.
所以目前他还剩下800个硬币。 I will have to find rank with current coins.
我将不得不找到当前硬币的排名。
For example, I have 5 records exist in my user reward against 3 subscriber ids.例如,我的用户奖励中有 5 条记录存在于 3 个订阅者 ID 中。 I want to get the rank of one subscriber against his subscription_id.
我想根据他的 subscription_id 获得一位订阅者的排名。
+-----------------+--------------+-------+
| subscription_id | date_awarded | coins |
+-----------------+--------------+-------+
| 525252 | 2020-09-11 | 10 |
| 454545 | 2020-09-11 | 20 |
| 989898 | 2020-09-11 | 10 |
| 525252 | 2020-09-10 | 50 |
| 454545 | 2020-09-10 | 30 |
+-----------------+--------------+-------+
The subscription ids 525252
has 60
coins, 989898 has 10
coins and 454545
has 50
coins.订阅 ID
525252
有60
硬币,989898 有10
硬币, 454545
有50
硬币。 But subscription id 525252
has used 40
of his coins, 40
coins are added in coins history table.但是,订阅ID
525252
采用了40
他的硬币, 40
硬币在硬币历史表添加。 So 454545
ranks first with 50
coins, 525252
ranks 2nd with 20
coins and 989898
ranks 3rd with 10
coins.因此,
454545
以50
硬币排名第一, 525252
以20
硬币排名第二, 989898
以10
硬币排名第三。
So for getting rank of user.所以为了获得用户的排名。 I get sum of coins from user reward table, then minus it with coins history table against that subscription id.
我从用户奖励表中获得硬币总和,然后根据该订阅 ID 用硬币历史记录表减去它。 Then find the rank against his current unused coins.
然后根据他当前未使用的硬币找到排名。 Below is my query, Query took 34.0794 sec.
以下是我的查询,查询耗时 34.0794 秒。
SELECT COUNT(*)+1 AS aboveRank
FROM
(
SELECT subscription_id
FROM user_rewards
GROUP BY subscription_id
HAVING SUM(coins) >
(Select (SELECT IFNULL(sum(coins), 0)
FROM user_rewards
WHERE subscription_id = 525252) -
(SELECT IFNULL(sum(coins), 0) as coins
FROM `coins_history`
where subscription_id = 525252) as z
)
) t
Note: I have around 800000 records in one month, it will keep on increasing daily, So need to optimize my current query, I am using MySQL and PHP.注意:我在一个月内有大约 800000 条记录,它会每天增加,所以需要优化我当前的查询,我使用 MySQL 和 PHP。
You can calculate the total coins per subscriber using union all
and group by
.您可以使用
union all
和group by
来计算每个订阅者的总硬币数。 Then use window functions for the ranking:然后使用窗口函数进行排名:
select c.*
from (select subscription_id, sum(coins) as coins,
rank() over (order by coins desc) as seqnum
from ((select subscription_id, - sum(coins) as coins
from user_rewards ur
group by subscription_id
) union all
(select subscription_id, sum(coins)
from coins_history ch
group by subscription_id
)
) c
group by subscription_id
) c
where subscription_id = ?;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.