繁体   English   中英

MySQL从300行中快速选择20条随机行

[英]MySQL select 20 random rows from 300 rows fast

我的数据库目前有300行,并且未来几年可能会增加到约5000行。 我想知道如何最好地随机选择20行。

我在这里发现MySQL从600K行中快速选择了10个随机行 (这里再次引用到http://jan.kneschke.de/projects/mysql/order-by-rand/ ),以下代码可以非常快速地产生随机选择:

SELECT name
  FROM random AS r1 JOIN
       (SELECT (RAND() *
                     (SELECT MAX(id)
                        FROM random)) AS id)
        AS r2
 WHERE r1.id >= r2.id
 ORDER BY r1.id ASC
 LIMIT 1

因此,在php中,我尝试了以下操作以获得20行:

$anfrage    =   "SELECT name
  FROM random AS r1 JOIN
       (SELECT (RAND() *
                     (SELECT MAX(id)
                        FROM random)) AS id)
        AS r2
 WHERE r1.id >= r2.id
 ORDER BY r1.id ASC
 LIMIT 20";

 $ergebnis=$db->query($anfrage)
        or die($db->error);
 while($zeile=mysqli_fetch_assoc($ergebnis))print_r($zeile);

但是,当我运行脚本时,大部分时间我不会得到20行。 实际上,从300个中选择20个不同的行的概率约为48.8%。

我可以更改上面的代码以非常快地获得20行吗?

如果阅读您在问题中提到的文章 ,您会发现有3种解决方案:

  • 多次执行查询
  • 编写执行查询的存储过程,并将结果存储在临时表中
  • 做一个联盟

所有这些都在文章中进行了解释。

获取20个随机名称的“缓慢”方式是这样的:

SELECT name
FROM random 
ORDER BY rand()
LIMIT 20;

在300行上,这可能与您使用的方法具有相似的性能。 你试过了吗? 我不确定大约5,000行,但是在那里也值得尝试。

您的方法本质上是这样(查询有点简化):

SELECT name
FROM random r1 CROSS JOIN
     (SELECT RAND() * MAX(id) as id FROM random) r2
WHERE r1.id >= r2.id
ORDER BY r1.id ASC
LIMIT 20;

您假设对每个迭代使用不同的值评估r2 该假设可能不正确。

另一种方法是这样做:

SELECT name
FROM random r1 CROSS JOIN
     (SELECT count(*) as cnt FROM random) const
WHERE rand() <= 20.0 / cnt;

不幸的是,这给出了大约的行数。 每次大约20次。 也许您真的想要20。在这种情况下,请执行以下操作:将预期的行数加倍,然后使用/ order by limit进行order by

SELECT name
FROM random r1 CROSS JOIN
     (SELECT count(*) as cnt FROM random) const
WHERE rand() <= 2*20.0 / cnt
ORDER BY rand()
LIMIT 20;

您可以创建一个随机整理的表,您偶尔可以对其进行更新:

INSERT INTO random_ids 
SELECT id 
FROM table_name
ORDER BY RAND();

记录在您的应用程序中插入的随机值的数量; 然后使用以下命令:

SELECT * FROM table_name
INNER JOIN (SELECT id 
    FROM random_ids
    LIMIT ?,20
) r1 ON r1.id = table_name.id;

因此,限制由您的应用程序确定为在[0, <count>)的范围内

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM