我已经阅读了很多关于这个主题的帖子,比如 mysql-get-rank-from-leaderboards.
但是,没有一种解决方案能够从数据库中获得一系列排名.
问题很简单.假设我们有一个带有"id"列的Postgres表和另一个值不是唯一的INTEGER列,但我们有一个该列的索引.
例如,桌子可能是:
CREATE TABLE my_game_users (id serial PRIMARY KEY, rating INTEGER NOT NULL);
Run Code Online (Sandbox Code Playgroud)
目标
尝试#1:row_number()窗口函数
WITH my_ranks AS
(SELECT my_game_users.*, row_number() OVER (ORDER BY rating DESC) AS rank
FROM my_game_users)
SELECT *
FROM my_ranks
WHERE rank >= 4000 AND rank <= 4050
ORDER BY rank ASC;
Run Code Online (Sandbox Code Playgroud)
这"工作",但在快速笔记本电脑上,查询平均550毫秒,100,000个用户,而没有任何其他实际工作.
我尝试添加索引,并重新措辞此查询以不使用"WITH"语法,没有任何方法可以加快速度.
尝试#2 - 计算具有更高评级值的行数 我尝试了这样的查询:
SELECT t1.*,
(SELECT COUNT(*)
FROM my_game_users t2
WHERE (t1.rating, -t1.id) <= (t2.rating, -t2.id)
) AS rank
FROM my_game_users t1
WHERE …Run Code Online (Sandbox Code Playgroud) 我们在面向微服务的架构中广泛使用Google Cloud Endpoints(GCE).所有服务均为Google App Engine.对于面向公众的GAE服务,我们将使用标准的Android OAuth对真实用户进行身份验证.但是,对于非面向用户的服务,我们希望我们的Cloud Endpoints受到保护(不公开),但可以通过默认的GAE服务帐户访问.
例如,内部支付服务可能希望联系内部用户服务以获取用户的配置文件,使用默认的GAE服务帐户进行身份验证,这样我们就不需要在代码中嵌入任何凭据.我们正在使用生成的Java库.
我正在使用这样的代码用生成的libs初始化服务:
public User createUserService() {
AppIdentityCredential credential = new AppIdentityCredential(Lists.newArrayList(OAUTH_EMAIL_SCOPE))
return new User.Builder(new UrlFetchTransport(), new JacksonFactory, credential)
.setRootUrl(userServiceRootUrl)
.build()
}
Run Code Online (Sandbox Code Playgroud)
我们还尝试使用GoogleCredential.getApplicationDefault()并在该凭据对象上设置范围.
从第一个GAE服务调用的目标端点具有如下代码:
@Api(
name = "user",
version = "v1",
clientIds = Array(Constants.APP_ENGINE_SERVICE_ACCOUNT_CLIENT_ID)
)
class UserEndpoints {
/**
* GET /user/:id
*
* Get a single user by id
*/
@ApiMethod(
httpMethod = HttpMethod.GET,
path = "user/{id}"
)
def find(
@Named("id") id: Long,
authUser: GoogleUser
): User = { …Run Code Online (Sandbox Code Playgroud)