一尘不染

只需一个查询即可获取不带ORDER BY RAND()的RAND()行

mysql

在MySQL中使用RAND()从巨大的表中获取单个随机行非常慢:

SELECT quote FROM quotes ORDER BY RAND() LIMIT 1

这是有关此问题的文章,以及为什么会这样。

他们的解决方案是使用两个查询:

SELECT COUNT(*) AS cnt FROM quotes

- Use result to generate a number between 0 and COUNT(*)

SELECT quote FROM quotes LIMIT $generated_number, 1

我想知道,是否只有一个查询就能做到这一点。

所以我的方法是:

SELECT * FROM quotes
LIMIT (
  ROUND(
    (SELECT COUNT(*) FROM quotes) * RAND()
  )
), 1

但是它暗示MySQL在Limit内不允许任何逻辑。尽管我找不到有关此主题的任何信息,但这是否是正确的。

所以我的问题:

  1. 如何在LIMIT内使用RAND()?
  2. 您是否知道其他任何解决方法,只需一个查询即可解决?

阅读 280

收藏
2020-05-17

共1个答案

一尘不染

有一个原因为什么不能使用存储过程来创建准备好的语句?

DELIMITER //
DROP PROCEDURE IF EXISTS rand_quote//
CREATE PROCEDURE rand_quote()
BEGIN
    SET @rand := ROUND((SELECT COUNT(*) FROM quotes) * RAND());
    SET @sql := CONCAT('SELECT * FROM quotes LIMIT ', @rand, ', 1');
    PREPARE stmt FROM @sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
END;
//
DELIMITER ;
2020-05-17