mysql rand()备选方案[必须满足某些标准]

mysql rand()备选方案[必须满足某些标准],mysql,random,Mysql,Random,我当前的查询是这样的 SELECT * FROM uploads WHERE approved = 1 AND (up-down) >= 3 ORDER BY RAND() LIMIT 10 这是从数据库中随机选择10个条目,其中至少有3个喜欢多于不喜欢 问题是因为我在DB中有超过40k个条目,而这个查询至少需要1秒 我在谷歌上读了很多书,但到目前为止什么也没找到 在我的情况下,您有什么建议吗?最佳方法取决于许多因素。这里有一些想法 假设没有索引,当前版本的查询将进行全表扫描,提

我当前的查询是这样的

SELECT *
FROM uploads
WHERE approved = 1
    AND (up-down) >= 3
ORDER BY RAND()
LIMIT 10
这是从数据库中随机选择10个条目,其中至少有3个喜欢多于不喜欢

问题是因为我在DB中有超过40k个条目,而这个查询至少需要1秒

我在谷歌上读了很多书,但到目前为止什么也没找到


在我的情况下,您有什么建议吗?

最佳方法取决于许多因素。这里有一些想法

假设没有索引,当前版本的查询将进行全表扫描,提取行,分配随机数,对行进行排序,然后选择前10行

第一次全表扫描可能会很慢,但在那之后应该会很快,假设表适合内存。假设您的性能问题不是指查询的第一个实例,而是指表已经在页面缓存中的实例

如果approved是高度选择性的(例如,1%的行被批准),那么您可以通过在approved上构建索引来加快查询速度

下一种选择是为up-down添加一列,并在approved和UpMinusDown这两个键上建立索引。假设这是选择性的,它可以降低速度

下一个问题是,你是否可以用其他一些标准来代替兰德,比如最近的10个标准。如果是这样,您可以包含一个主键,比如UploadID,并将其用于排序。它会走得更快

最后,如果您的记录非常广泛,则可能是占用时间的类型。在这种情况下,我想知道以下版本的查询是否会执行得更好:

SELECT *
FROM uploads u left outer join
     (select UploadID
      from uploads
      WHERE approved = 1
            AND (up-down) >= 3
     ORDER BY RAND()
     LIMIT 10
    ) random
    on u.UploadID = random.UploadID
这假定表上有一个名为UploadID的主键


这个版本应该只对UpLoadID进行排序,然后使用索引将其连接回原始数据。

如果您正在将所有匹配的记录加载到内存中,并且没有太多记录,那么最简单的答案就是在SQL中删除顺序,然后在应用软件中随机排序。例如,如果您使用的是PHP,您可以简单地将它们全部加载到一个数组中,然后调用array\u rand

如果这不是一个合适的答案,那么您仍然需要在DB中对它们进行排序,然后在order by rand太慢的情况下,即在您拥有大量数据的大多数情况下,我知道的最佳解决方案如下:

向表中添加一个新列,并使用每个记录的主键的MD5散列对其进行预填充。并添加一个索引以按新字段排序


这将为表提供均匀分布的随机排序顺序。只需按此字段而不是按随机数排序。

列上有索引吗?有多少行符合WHERE标准?如果不使用ORDER BY,查询需要多长时间?是否可以更改架构?是的,我有索引。42k行中有24k行与where条件匹配。如果不使用ORDER BY,则需要大约半秒钟。条目总是相同的。我不希望更改架构,但如果需要的话可以。我在上面提到的所有列上都做了标记。还有一列“id”,它是主索引自动增量。大多数上传都是approved95%+。是的,我知道显示10条最新记录是一种方式,但我也需要随机函数。如果他使用MD5哈希并按此排序,每次查询时都会给出相同的10个元素。不是很随机。是的,第一个答案不合适,因为24k记录匹配,所以在内存中加载每个用户发出的请求是不明智的。但是我不明白你所说的散列主键是什么意思。我的主键是字段ID,它会自动增加每次上载的数量。通过“按主键散列”,我只是假设主键是每个记录的唯一值。因此,它将为每个记录提供唯一的哈希值。实际值是不相关的-它不必是主键,它可以是每个记录唯一的任何其他值;重要的一点是,MD5散列值提供了一个很好的随机顺序,只要您为每个散列使用一个唯一的值。@Barmar-这是正确的,但有一些方法可以缓解它。例如,重新填充已查询记录的哈希。但真正的问题是,这是速度问题的解决方案。最后,如果需要快速查询,则需要查询索引;如果需要快速随机查询,则需要查询随机排序的索引。问题是绩效有多重要?