Я получил очень низкую производительность по этому запросу, чтобы получить рейтинг игроков за таблицу лидеров. Он растет экспоненциально по мере роста числа записей (как и ожидалось). Есть ли способ оптимизировать это? Я считал, что я могу рассчитать это поле при каждом обновлении в качестве альтернативы этому:
SELECT 's1'.*,COUNT(DISTINCT 's2'.'score') AS 'rank' FROM 'leaderboards' 's1'
JOIN 'leaderboards' 's2'
ON('s1'.'score' <= 's2'.'score' AND 's1'.'leaderboard' = 's2'.'leaderboard')
GROUP BY 's1'.'leaderboard','s1'.'user_id';
убедитесь, что у вас есть правильный составной индекс
table leaderboards (leaderboard, score)
и вы не используете столбец в select, который не задействован в функции агрегации и не упоминается в предложении group by, потому что thii создает непредсказуемый результат для этих столбцов, эта привычка устарела в SQL и в последней версии mysql создает ошибку
SELECT 's1'.'leaderboard','s1'.'user_id', COUNT(DISTINCT 's2'.'score') AS 'rank'
FROM 'leaderboards' 's1'
JOIN 'leaderboards' 's2' ON 's1'.'score' <= 's2'.'score'
AND 's1'.'leaderboard' = 's2'.'leaderboard'
GROUP BY 's1'.'leaderboard','s1'.'user_id';
try as below:
ALTER TABLE 'leaderboards' ADD INDEX ('leaderboard');
SELECT 's1'.*,COUNT(DISTINCT 's2'.'score') AS 'rank'
FROM 'leaderboards' 's1'
LEFT JOIN 'leaderboards' 's2'
ON('s1'.'score' <= 's2'.'score' AND 's1'.'leaderboard' = 's2'.'leaderboard')
GROUP BY 's1'.'leaderboard','s1'.'user_id';
SET @rank:=0; SELECT *, @rank := IF(score = @prev, @rank, @rank+1) AS rank, @prev:=score AS prvs FROM leaderboards WHERE leaderboard = 'leaderboard_name' ORDER BY score DESC;