首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用低成本的MySql更新

使用低成本的MySql更新
EN

Stack Overflow用户
提问于 2013-01-16 23:47:28
回答 1查看 155关注 0票数 0

我正在我的应用程序中实现一个排行榜,我想每隔几次更新一次。为此,我创建了两个排行榜表格,每个表格看起来像这样:

代码语言:javascript
运行
复制
user_id, score, rank

下面是我的更新查询:

代码语言:javascript
运行
复制
select score from leaderboard order by score for update;
select(@rankCounter := 0);
update leaderboard set rank = (select(@rankCounter := @rankCounter + 1)) order by score desc;

我正在使用我的活动表进行查询,并且每隔几次就切换一次活动表。

更新目前大约需要3分钟(在我的机器上)来更新4M个raws。我希望减少CPU的使用量,我不关心更新会花更长的时间。

我该怎么做呢?

EN

回答 1

Stack Overflow用户

发布于 2013-01-17 01:01:40

我建议您尝试添加一个索引... ON leaderboard (score),以避免排序操作。我还建议您从UPDATE语句中删除不必要的SELECT (但我不知道这是否对性能有影响,但SELECT关键字在该上下文中不是必需的。

排序操作肯定会使用一些CPU。我不清楚是优化器忽略了UPDATE语句中SELECT语句,还是计划与此不同(不必要?)在那里选择。(在该上下文中包含SELECT关键字的目的是什么?)

此外,没有必要从每一行返回分值来获得排行榜中所有行的锁。SELECT语句上的ORDER BY也可能消耗CPU周期(如果没有以score作为前导列的索引)。不必要的4M行结果集的准备也会消耗CPU周期。

不清楚为什么有必要使用SELECT ...对于UPDATE,当UPDATE语句本身将获得必要的锁时。( SELECT ...FOR UPDATE语句将仅在BEGIN TRANSACTION上下文中或禁用自动提交的情况下获得锁。(这里我假设leaderboard是一个InnoDB表。)

MySQL可以利用索引来避免排序操作:

代码语言:javascript
运行
复制
CREATE INDEX leaderboard_IX1 ON leaderboard (score) ;

这应该足以更新排名列:

代码语言:javascript
运行
复制
SET @rankCounter := 0;
UPDATE leaderboard
  SET rank = @rankCounter := @rankCounter + 1
ORDER BY score DESC ;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14362304

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档