只在一个查询中获取没有ORDER BY RAND()的RAND()行

Joc*_*ung 2 mysql random query-optimization

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

SELECT quote FROM quotes ORDER BY RAND() LIMIT 1
Run Code Online (Sandbox Code Playgroud)

这是一篇关于这个问题的文章以及为什么会这样.

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

SELECT COUNT(*) AS cnt FROM quotes

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

SELECT quote FROM quotes LIMIT $generated_number, 1
Run Code Online (Sandbox Code Playgroud)

我想知道,这是否只能在一个查询中实现.

所以我的方法是:

SELECT * FROM quotes
LIMIT (
  ROUND(
    (SELECT COUNT(*) FROM quotes) * RAND()
  )
), 1
Run Code Online (Sandbox Code Playgroud)

但它接缝MySQL不允许任何逻辑限制.虽然我找不到关于这个主题的任何信息,但这是否属实.

所以我的问题:

  1. 如何在LIMIT中使用RAND()?
  2. 你知道有任何其他方法只用一个查询来解决这个问题吗?

Mik*_*ike 5

是否有理由不能使用存储过程来创建预准备语句?

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 ;
Run Code Online (Sandbox Code Playgroud)