代码之家  ›  专栏  ›  技术社区  ›  JochenJung

只在一个查询中获取RAND()行而不按RAND()排序

  •  2
  • JochenJung  · 技术社区  · 14 年前

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

    SELECT quote FROM quotes ORDER BY RAND() LIMIT 1
    

    Here is an article 关于这个问题以及为什么会这样。

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

    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
    

    虽然我找不到关于这个话题的任何信息,但这是否属实。

    所以我的问题是:

    1. 如何在限制内使用RAND()?
    2. 只需一个查询就能解决这个问题?
    3 回复  |  直到 14 年前
        1
  •  5
  •   Mike    14 年前

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

    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 ;
    
        2
  •  1
  •   JochenJung    14 年前

    我刚画了这个,就像一个解决方案:

    SELECT * FROM quotes
    WHERE quotes_id = ROUND(
      (SELECT COUNT(*) FROM quotes) * RAND()
    )
    LIMIT 1
    

        3
  •  1
  •   Roman Losev    9 年前

    我通过检查max id解决了这个问题,然后我创建了rand(0,max\u id)的php循环来检查对象是否存在。完成。