Question

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 !!!!!

Was it helpful?

Solution

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;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top