sql - MySQL:ORDER BY RAND() 的替代方案

我已经阅读了 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 

最佳答案

2016 年更新

此解决方案使用索引列效果最佳。

这是一个简单的示例,经过优化的查询台标有 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/

相关文章:

mysql - phpmyadmin.pma_table_uirefs 不存在

mysql - 在 MySQL 查询中结合 UNION 和 LIMIT 操作

mysql - 从另一列计算的列?

mysql - 从mysql中的表中删除所有记录

mysql - 在 Windows 7 上重新启动 mysql 服务器

mysql - 如何向现有表添加唯一键(具有非唯一行)

mysql - 查找和替换整个 MySQL 数据库

mysql - 如何在 Amazon RDS 数据库服务器实例上运行命令 "mysqladmin f

MySQL - 使用 LIMIT 更新查询

mysql - 将主机访问权限重新分配给 MySQL 用户