SELECT
all_ranked.*
FROM (select rank
from (SELECT l.id AS id2,
@curRow := @curRow + 1 AS Rank
FROM scores l
JOIN
(SELECT @curRow := 0) r
ORDER BY scr DESC, dateupdated ASC
) AS B)
where B.id=1234567) as rank_record, <--- just one record - value of rank
(SELECT l.id AS id2,
@curRow := @curRow + 1 AS Rank
FROM scores l
JOIN
(SELECT @curRow := 0) r
ORDER BY scr DESC, dateupdated ASC
) AS all_ranked <--- all ranked users
where all_ranked.rank>=rank_record.rank-5 and all_ranked.rank>=rank_record.rank+5;
MySql : Get Ranks Heavy Query Optimization - help needed
Frage
i've only got the following table in my database :
scores Table
Field...............|........Type.........|..Null..|..Key..|...........Default.................|..Extra
...............................................................................................................................................
id....................|...........int(20)...|..NO...|..PRI..|..NULL.............................|..auto_increment
scr..................|...........int(20)...|..NO...|..........|.....0.................................|..........................
player_name..|..varchar(150)..|..NO...|..........|..NULL............................|.........................
location...........|.varchar(5).......|..NO...|..........|..NULL............................|.........................
DateUpdated..|..timestamp......|..NO...|..........|CURRENT_TIMESTAMP|..on-update
currently i've got an index on the id field .
i'm dealing with 1 million records in my case . each player will have one record only in the database.
i want to retrieve the global ranking of a specific player named : john with id : 682 as per the following example:
Rank..........Id.......SCR......DateUpdated
-------------------------------------------------------------
15257...53264.......62........2013-3-10 16:45:37
15258...3533.........62........2013-3-10 16:45:37
15259...7283.........62........2013-3-13 16:45:37
15260...386...........61........2013-3-09 18:55:25
15261...78252.......61........2013-3-10 13:33:21
15262...682...........61........2013-3-10 16:45:37 <== this is our player
15263...9263.........61........2013-3-10 16:45:37
15264...7263.........61........2013-3-10 16:56:25
15265...7826.........60........2013-3-10 12:26:37
15266...9276.........60........2013-3-10 15:22:37
15267...932872.....60........2013-3-13 11:45:37
the player appears in the middle with 5 players above and 5 players below Note that ranks is ordered by scr then DateUpdated
this is my query which brings these results :
SELECT id,
scr,
player_name,
location,
dateupdated,
rank
FROM
(SELECT id,
scr,
player_name,
location,
dateupdated
FROM scores
WHERE id IN
(SELECT id
FROM
(SELECT id
FROM scores
WHERE id IN
(SELECT id
FROM scores
WHERE scr >=
(SELECT scr FROM scores WHERE id = 1140188
)
AND id != 1140188
AND id NOT IN
(SELECT id
FROM scores
WHERE scr IN
(SELECT scr FROM scores WHERE id = 1140188
)
AND dateupdated >=
(SELECT dateupdated FROM scores WHERE id = 1140188
)
)
ORDER BY scr ASC,
dateupdated ASC
)
ORDER BY scr,
dateupdated ASC limit 0,
5
) AS t
UNION ALL
SELECT id FROM
(SELECT id FROM scores WHERE id = 1140188
) AS g
UNION ALL
SELECT id
FROM
(SELECT id
FROM scores
WHERE id IN
(SELECT id
FROM scores
WHERE scr <=
(SELECT scr FROM scores WHERE id = 1140188
)
AND id != 1140188
AND id NOT IN
(SELECT id
FROM scores
WHERE scr IN
(SELECT scr FROM scores WHERE id = 1140188
)
AND dateupdated <
(SELECT dateupdated FROM scores WHERE id = 1140188
)
)
ORDER BY scr ASC,
dateupdated ASC
)
ORDER BY scr DESC,
dateupdated ASC limit 0,
5
) AS s
)
ORDER BY scr DESC,
dateupdated ASC
) AS A
LEFT JOIN
(SELECT l.id AS id2,
@curRow := @curRow + 1 AS Rank
FROM scores l
JOIN
(SELECT @curRow := 0
) r
ORDER BY scr DESC,
dateupdated ASC
) AS B ON A.id = B.id2;
but this query takes around 8 sec on my local machine and it consumes a lot of resources, implementing this on a web service will end up in a disaster.
can any one provide any hints here, even an entirely new query is welcomed ..
please HELP !!!!!
Lösung