我已经阅读了 MySQL 的 ORDER BY RAND()
函数的一些替代方案,但大多数替代方案仅适用于需要单个随机结果的地方。
有谁知道如何优化返回多个随机结果的查询,例如:
SELECT u.id,
p.photo
FROM users u, profiles p
WHERE p.memberid = u.id
AND p.photo != ''
AND (u.ownership=1 OR u.stamp=1)
ORDER BY RAND()
LIMIT 18
最佳答案
此解决方案使用索引列效果最佳。
这是一个简单的示例,经过优化的查询台标有 100,000 行。
优化:300ms
SELECT
g.*
FROM
table g
JOIN
(SELECT
id
FROM
table
WHERE
RAND() < (SELECT
((4 / COUNT(*)) * 10)
FROM
table)
ORDER BY RAND()
LIMIT 4) AS z ON z.id= g.id
关于限制数量的说明:限制 4 和 4/count(*)。 4s 必须是相同的数字。更改返回的数量不会对速度产生太大影响。限制 4 和限制 1000 的基准是相同的。限制 10,000 耗时长达 600 毫秒
关于加入的注意事项:仅随机化 id 比随机化整行要快。由于它必须将整行复制到内存中,然后将其随机化。连接可以是链接到子查询的任何表,以防止表扫描。
注意 where 子句:where 计数限制了随机化结果的数量。它采用一定百分比的结果并对它们进行排序,而不是对整个表进行排序。
注意子查询:如果做连接和额外的 where 子句条件,您需要将它们放在子查询和子子查询中。进行准确的计数并拉回正确的数据。
未优化:1200 毫秒
SELECT
g.*
FROM
table g
ORDER BY RAND()
LIMIT 4
优点
比 order by rand()
快 4 倍。此解决方案可用于任何具有索引列的表。
缺点
复杂的查询有点复杂。需要在子查询中维护2个代码库
https://stackoverflow.com/questions/1823306/