【问题标题】:RAND() Query and PerformanceRAND() 查询和性能
【发布时间】:2011-03-26 20:20:18
【问题描述】:

我正在尝试为性能准备一个查询。我希望从下面的查询中删除 RAND() 并将其替换为性能更好的替代方案。有人有什么建议吗?

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

谢谢!

【问题讨论】:

标签: mysql sql random sql-order-by


【解决方案1】:

在调用此查询的语言中,在 LIMIT 的偏移中使用随机数,而不是使用 RAND()。这可能有两个问题。您需要知道数据库中有多少项目,2. 只为其中一个项目产生随机的东西。其他选项是完全放弃 LIMIT 和 RAND() 并在返回查询时选择随机项(我想这会更慢)

您需要如此高的性能是否有真正的原因?我很确定使用 RAND() 对这种查询就足够了。

【讨论】:

  • ORDER BY RAND() 的性能取决于正在处理的记录数。
  • 在选择两个随机记录之前,我已经返回了记录计数。我可能会以此为基础。
【解决方案2】:

代替in 子查询,尝试排他左连接?这样一来,MySQL 就知道它不必扫描video 表两次:

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

【讨论】:

  • 取决于VIDEO_LOG.videoid 是否可以为NULL——如果可以,NOT EXISTS 是更好的选择。否则,LEFT JOIN/IS NULL 是最佳选择(看起来像外键,所以这可能是最佳选择)。但这并不能解决使用 ORDER BY RAND() 的性能问题,它从 100+K 条记录开始。
  • video_log 在某些情况下将为空。当我达到 10 万条记录时会出现什么样的性能问题?
猜你喜欢
  • 2012-12-28
  • 2015-09-14
  • 2016-03-09
  • 1970-01-01
  • 1970-01-01
  • 2013-06-07
  • 2017-07-26
  • 2012-07-18
  • 2014-03-06
相关资源
最近更新 更多