我的数据库目前有300行,并且在接下来的几年中可能会增加到约5000行。我想知道如何最好地随机选择20行。
我在这里找到MySQL select 10 random rows from 600K rows fast(再次提到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 行吗?
答案 0 :(得分:0)
答案 1 :(得分:0)
获得20个随机名称的“缓慢”方式是:
SELECT name
FROM random
ORDER BY rand()
LIMIT 20;
在300行上,这可能与您使用的方法具有相似的性能。你试过吗?我不确定5000行,但也值得尝试。
你的方法基本上就是这个(查询有点简化):
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
:
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;
答案 2 :(得分:0)
您可以创建一个偶尔更新的混洗表:
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>)