I am trying to get a list of "active" users ordered by their last activity and paginated. I had it working originally as a basic join, but when I added a few 100,000's of test users, the query would take longer and longer as you paginated and take absolutely ages by the time you got to the last page.
I then nested the join to fix the speed issues, but I am unable to order the results properly due to the outer query which returns only active users with the offset and limit before the order can be applied.
Here's the current query;
$sql = "SELECT * FROM (
SELECT roles_users.*, users.last_active FROM roles_users, users
WHERE roles_users.role_id = '2'
LIMIT $offset, $limit
) AS role
LEFT JOIN users ON users.id = role.user_id
WHERE
users.f_name IS NOT NULL
AND users.city IS NOT NULL
AND users.gender IS NOT NULL
AND users.date_of_birth IS NOT NULL
ORDER BY users.last_active DESC";
What is the best way of doing this so that it runs efficiently and orders correctly?
EDIT
Table structure for roles_users;
#-- Field -- Type ----------- Null -- Key --- Foreign key --#
#
# user_id int(10) unsigned No primary users.id
# role_id int(10) unsigned No primary user_roles.id
#
#############################################################
The users table is quite extensive so I won't put it here. It is fairly standard though.
There is an index on users.last_active.