我环顾四周,似乎没有任何简单的方法可以做到这一点。它几乎看起来只是抓取一部分记录并在代码中完成所有随机化(perl)。我在网上看到的方法看起来更像是数十万,但肯定不是数百万。
与我合作的表有600万条记录(并且还在增长),ID会自动递增,但并不总是存储在表格中(非无间隙)。
我已经尝试过推荐的LIMIT 1查询,但是查询需要永远运行 - 考虑到记录中存在空白,是否可以快速执行此操作?我不能只接受最大值并在范围内随机化。
更新
我的一个想法可能是获取最大值,根据最大值随机化一个限制,然后从random_limit_1到random_limit_2获取10个记录的范围,然后获取在该范围内找到的第一个记录。
或者,如果我知道最大值,有没有办法可以选择说出表的第5条记录,而不必知道它是哪个ID。然后抓住该记录的ID。
更新
这个查询有点快 - 是的。仍然不够快= /
SELECT t.id FROM table t JOIN (SELECT(FLOOR(max(id) * rand())) as maxid FROM table) as tt on t.id >= tt.maxid LIMIT 1
答案 0 :(得分:8)
SELECT * FROM TABLE ORDER BY RAND() LIMIT 1;
好的,这很慢。如果你要搜索ORDER BY RAND() MYSQL
,你会发现很多结果都说这很慢,而且情况确实如此。我做了一点研究,发现了这个替代MySQL rand() is slow on large datasets
我希望这更好
答案 1 :(得分:7)
是的,想法似乎很好:
select min(ID), max(ID) from table into @min, @max;
set @range = @max - @min;
set @mr = @min + ((@range / 1000) * (rand() * 1000));
select ID from table
where ID >= @mr and ID <= @mr + 1000
order by rand()
limit 1
-- into @result
;
可以将1000更改为10000或根据需要进行缩放......
编辑:你也可以试试这个:select ID from table
where (ID % 1000) = floor(rand() * 1000)
order by rand()
limit 1
;
按不同的方式拆分......
编辑2:
请参阅:What is the best way to pick a random row from a table in MySQL?
这可能是最快的方式:
select @row := floor(count(*) * rand()) from some_tbl;
select some_ID from some_tbl limit @row, 1;
遗憾的是,变量不能在limit子句中使用,因此您必须使用动态查询,在代码中编写查询字符串,或使用PREPARE和EXECUTE。此外,限制n,1仍需要将n个项目扫描到表格中,因此它的速度仅为上面列出的第二种方法的两倍。 (虽然它可能更均匀,并保证始终找到匹配的行)
答案 2 :(得分:0)
SELECT ID
FROM YourTable
ORDER BY RAND() LIMIT 1;