I'm using this query to fetch user's rank from Sql Server DB:
select user_rank
from (select t.user_id, rank() over (order by score desc) as user_rank
from user_stats t
) t
where t.user_id='some_user_id';
The table consists approximately 22,000 rows and the query takes 3.5 seconds, which is too slow.
There are several indexes on this table, these are the relevant:
user_id - Unique, NONCLUSTERED INDEX
score - Non-unique, NONCLUSTERED INDEX
If I change the query and use id (which is my primary key) instead of user_id, then the query executes fast:
select user_rank
from (select t.id, rank() over (order by score desc) as user_rank
from user_stats t
) t
where t.id='some_id';
After checking the Execution plan I see that Clustered index scan cost is 92%, though I don't really understand why it's needed in this case.
What can be done to optimize this query?
The statistics of the query:
SQL Server parse and compile time: CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times: CPU time = 0 ms, elapsed time = 0 ms. SQL Server parse and compile time: CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times: CPU time = 0 ms, elapsed time = 0 ms. SQL Server parse and compile time: CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times: CPU time = 0 ms, elapsed time = 0 ms. SQL Server parse and compile time: CPU time = 0 ms, elapsed time = 0 ms.
(1 row(s) affected) Table 'users_stats'. Scan count 1, logical reads 22529, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(1 row(s) affected)
SQL Server Execution Times: CPU time = 78 ms, elapsed time = 3576 ms. SQL Server parse and compile time: CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times: CPU time = 0 ms, elapsed time = 0 ms.