以下查询实际上如何运作?
SELECT * FROM t ORDER BY RAND() LIMIT 1;
它首先对源数据库中的所有记录进行排序,然后将其截断以获得1行吗?
答案 0 :(得分:2)
此问题与LIMIT
查询优化有关,而与RAND()
的工作方式有关。
来自manual(大胆强调我的):
如果将 LIMIT row_count 与ORDER BY 结合使用,MySQL 会在找到第一个row_count后立即排序 / strong>排序结果的行,而不是整个结果的排序。
如果使用索引进行排序,则速度非常快。 如果必须完成文件分类,则选择所有行且不选择LIMIT子句的查询,并对其中的大部分或全部进行排序,找到第一个row_count之前 。在找到初始行之后,MySQL不会对结果集的任何剩余部分进行排序。
答案 1 :(得分:1)
是。在限制结果之前执行按操作排序。
要获得性能良好的随机记录,您必须使用其他方法。
解决方案是: 如果您有一个顺序的id,您可以创建一个随机数,并仅通过where子句获取该记录:
Select * from t
where id>(select * from
(select rand()*10000)t1
) limit 1;
10000是表格中最大的ID。
为了使查询更具动态性,我们可以使用:
SET @m:=rand()*(select max(id) from t);
SELECT * FROM t WHERE id > @m LIMIT 1;
这也有效:
Select * from t
where
id>(select * from(select rand()*max(id) from t) t1)
limit 1;
但是以下查询不正确,并且在开头只显示大约0.5%的记录。我不知道为什么:
Select * from t
where
id>rand()*(select max(id) from t)
limit 1;