Tron
Tron

Reputation: 703

Help me optimize a query for random records

I currently have a query for random records that's mad inefficient because it's ordering by RAND() and creating a temporary table each time it's called. Also, this means that it cannot be cached. It is also joined to another table which adds processing time and complicates things a little. So, help me optimize the following:

SELECT     listings.id, listings.price, listings.seller_id, sellers.blacklisted
FROM       listings
INNER JOIN sellers ON sellers.id = listings.sellers_id
WHERE      listings.price > 100
AND        sellers.blacklisted = 0
ORDER BY   RAND()
LIMIT 4

One way to start going about this is to run one query that returns a COUNT() of the possible listings, then a second query (or 4 others if it's to be truly random) with an offset set within RAND()*COUNT.

How would you approach this?

Upvotes: 1

Views: 121

Answers (1)

Ben
Ben

Reputation: 52863

Assuming that listings is indexed on id:

If your id is an integer:

SELECT     listings.id, listings.price, listings.seller_id, sellers.blacklisted
FROM       listings
INNER JOIN sellers ON sellers.id = listings.sellers_id
WHERE      listings.price > 100
AND        sellers.blacklisted = 0
AND        listings.ID LIKE CONCAT(CEIL(RAND() * 100),'%')
LIMIT 4

and if it's ascii

SELECT     listings.id, listings.price, listings.seller_id, sellers.blacklisted
FROM       listings
INNER JOIN sellers ON sellers.id = listings.sellers_id
WHERE      listings.price > 100
AND        sellers.blacklisted = 0
AND        listings.ID LIKE CONCAT(CHAR(CEIL(RAND() * 100)),'%')
LIMIT 4

basically my advice to speed things up is dump the order by. On anything over a few records you're adding measurable overhead.

ps please forgive me if concat can't be used this way in mqsql; not entirely certain whether it'll work.

Upvotes: 1

Related Questions