Если бы вы залили тестовые данные куда-то, было бы проще проверить, но так есть вот такой трюк с MySQL — не факт, что это будет работать быстрее, и выглядит это жутко, так что выбор использовать это или нет исключительно за вами :)
SELECT
t.map_id,
t.score,
pd.level
FROM
(SELECT
ms1.map_id,
ms1.score,
ms1.user_id
FROM
MapsScores ms1
LEFT JOIN MapsScores ms2
ON ms1.map_id = ms2.map_id
AND ms1.score >= ms2.score
GROUP BY ms1.map_id,
ms1.score
HAVING COUNT(*) <= 20) t
LEFT JOIN PlayersData pd
ON t.user_id = pd.uid
ORDER BY 1,
2 DESC