从随机选择的用户ID集合中选择随机行[mysql]

时间:2014-05-01 21:11:15

标签: mysql random

场景:(我使用MySQL)

这是我的架构:

CREATE TABLE so_time_diff(
  OwnerUserId int(11),
  time_diff int(10)
);

有很多OwnerUserId,每个OwnerUserId都有很多time_diff值。

我想选择1000个随机不同的OwnerUserIds,并且对于每个OwnerUserId,只选择一个随机time_difference值。

我已经从其他地方获得了1000个不同的OwnerUserIds并存储在另一个表中:

mysql> create table so_OwnerUserId select distinct(Id) as OwnerUserId
from so_users order by RAND() limit 1000;

我写了以下查询:

select @td := time_diff from so_time_diff sotd, so_OwnerUserId soui 
where sotd.OwnerUserId = soui.OwnerUserId group by sotd.OwnerUserId
order by rand() limit 1;

这似乎没有达到我想要的效果。它显然只返回一行。但我希望每个OwnerUserId的time_diff集合中有一个随机行。有人可以指导我如何实现这个目标吗?

仅供参考 - 数据集的大小很大 - 约5600万条记录。所以我正在寻找最佳查询。

任何帮助表示感谢。

谢谢!

1 个答案:

答案 0 :(得分:1)

一种方法是使用相关子查询。它不是一种非常有效的方法,因为该子查询将针对外表中的每一行执行,如果so_OwnerUserId中有1000行,则该子查询将为1000次。

SELECT r.OwnerUserId
     , ( SELECT d.time_diff
           FROM so_time_diff d
          WHERE d.OwnerUserId = r.OwnerUserId
          ORDER BY RAND()
          LIMIT 1
       ) AS random_time_diff
  FROM so_OwnerUserId r

对于任何类型的性能,您需要在OwnerUserId表上使用前导列so_time_diff的索引。更好的是,覆盖指数

... ON so_time_diff (OwnerUserId, time_diff) 

(对于InnoDB,如果这些是表中仅有的两列,那么您希望将其作为群集密钥。)