When I first made this query and the table was relatively small, it ran very quickly, but over time as the update table size increased (now about 6000 rows) the query has been extrememly slow and resource intensive. The server I’m using is the 1GB RAM VPS from linode.com, and I haven’t actually waited long enough for the query to finish.
Interestingly, without the extra condition in the left join (SELECT MAX(u2.time)) it runs in < 0.5s.
I had a look in the process list of mySQL while the query was running, and it showed as ‘Sending Data’ for the whole time
Here’s the query:
SELECT
s.ID as sid, s.country AS country,
s.name AS name, s.ip AS ip,
u.connPlayers AS cp, u.maxPlayers AS mp
FROM servers AS s
LEFT JOIN updates AS u
ON u.serverID = s.ID
AND u.time =
(SELECT MAX(u2.time)
FROM updates AS u2
WHERE u2.serverID = s.ID)
ORDER BY RAND(MINUTE(NOW()))
LIMIT 0,10
And here’s the my.cnf file: http://redream.co.nz/my.cnf
Table structure:
Servers table (20 rows
)
Field Type
ID int(10) Unique Key
ip varchar(200)
country varchar(2)
name varchar(600)
motd varchar(600)
desc mediumtext
version varchar(600)
Update table (6000 rows)
Field Type
serverID int(10)
ping int(10)
time int(14)
uptime int(10)
connPlayers int(10)
maxPlayers int(10)
uptime int(14)
I am no MySQL expert, but I think this will work for MySQL:
The important change is that the left join now contains the following subquery:
This subquery again contains a subquery and returns for each serverId the row with the maximum time value. The above subquery is only executed once instead of for each row in the cross product.