0

I'm trying to prepare a query for performance. I'm hoping to remove the RAND() from the query below and replace it with a better performing alternative. Does anybody have any suggestions?

SELECT video.*, 
       video.wins / video.loses AS win_loss_ratio
  FROM video
 WHERE video.videoid NOT IN (SELECT vidlog.videoid
                               FROM video AS vid, 
                                    video_log AS vidlog
                              WHERE vid.videoid = vidlog.videoid)
   AND video.round = 0
ORDER BY RAND(), win_loss_ratio DESC 
LIMIT 0, 2

Thanks!

OMG Ponies
  • 325,700
  • 82
  • 523
  • 502
Tegan Snyder
  • 785
  • 7
  • 12
  • possible duplicate of [MySQL: Alternatives to ORDER BY RAND()](http://stackoverflow.com/questions/1823306/mysql-alternatives-to-order-by-rand) – OMG Ponies Mar 26 '11 at 20:25
  • thanks for pointing this link out. I did some searching prior to the post; however, i was interested in opinions on my entire query. – Tegan Snyder Mar 26 '11 at 22:31

2 Answers2

1

Instead of using the RAND() use a random number in the offset for the LIMIT in the language that is calling this query. That could have two problems though a. you need to know how many items are in the database, 2. only yield something random for one of the items though. Other option is to drop the LIMIT and RAND() altogether and just select random items when the query is returned (I would imagine this to be slower though)

Is there a real reason why you need to have this very high in performance? I'm pretty sure using RAND() will be sufficient enough for this kind of query.

Gary Green
  • 22,045
  • 6
  • 49
  • 75
0

Instead of the in subquery, try an exclusive left join? That way, MySQL knows it doesn't have to scan the video table twice:

SELECT  video.* 
,       video.wins / video.loses AS win_loss_ratio
FROM    video
LEFT JOIN    
        video_log as vidlog
ON      vid.videoid = vidlog.videoid
WHERE   vidlog.videoid is null
        AND video.round =0
ORDER BY 
        RAND()
LIMIT   0 , 2
Andomar
  • 232,371
  • 49
  • 380
  • 404
  • Depends on if the `VIDEO_LOG.videoid` can be NULL -- if it can, `NOT EXISTS` is a better choice. Otherwise, `LEFT JOIN/IS NULL` is the best choice (looks like a foreign key, so likely this is the best choice). But that doesn't address the performance issue regarding using `ORDER BY RAND()`, which begins at 100+K records. – OMG Ponies Mar 26 '11 at 20:33
  • video_log will be null on certain occasions. what kind of performance issues will begin when i hit 100k records? – Tegan Snyder Mar 26 '11 at 22:29