【问题标题】:Quickly select random ID from mysql table with millions of non-sequential records从具有数百万非顺序记录的mysql表中快速选择随机ID
【发布时间】:2012-01-16 23:48:04
【问题描述】:

我环顾四周,似乎没有任何简单的方法可以做到这一点。它几乎看起来更容易抓住记录的子集并在代码中进行所有随机化(perl)。我在网上看到的方法似乎更多的是针对最多数十万,但肯定不是数百万。

我正在使用的表有 600 万条记录(并且还在增长),ID 会自动递增,但并不总是存储在表中(无间隙)。

我已尝试执行推荐的 LIMIT 1 查询,但查询需要永远运行 - 鉴于记录中存在空白,是否有快速的方法来执行此操作?我不能只取最大值并在范围内随机化。

更新:

我的一个想法可能是获取最大值,根据最大值随机化一个限制,然后获取从 random_limit_1 到 random_limit_2 的 10 条记录,然后获取在该范围内找到的第一条记录。

或者如果我知道最大值,有没有办法我可以选择表的第 5 条记录,而不必知道它是哪个 ID。然后只需获取该记录的 id。

更新:

这个查询有点快。还是不够快=/

SELECT t.id FROM table t JOIN (SELECT(FLOOR(max(id) * rand())) as maxid FROM table) as tt on t.id >= tt.maxid LIMIT 1

【问题讨论】:

  • non-gapless 是什么意思?有差距吗?
  • 相当肯定 nodebunny 表示一个典型的自动增量索引,过去删除了一些行...
  • 您帖子中的更新查询在我的系统上总共运行了大约 0.005 秒,您希望它运行多快?

标签: mysql random recordset


【解决方案1】:
SELECT * FROM TABLE ORDER BY RAND() LIMIT 1;

好的,这很慢。如果你搜索ORDER BY RAND() MYSQL,你会发现很多结果说这很慢,事实就是如此。我做了一些研究,发现了这个替代方案MySQL rand() is slow on large datasets 我希望这会更好

【讨论】:

  • 是的,我试过了,但即使在限制 1 上,查询也需要 FOREVERS 才能运行。
  • 该链接上的查询 SELECT t.id FROM table t JOIN (SELECT(FLOOR(max(id) * rand())) as maxid FROM table) as tt on t.id >= tt .maxid LIMIT 1 稍快——仍然太慢 =/
  • 我不认为链接连接查询会给出非常统一的随机结果,除非添加了 ID 顺序?
【解决方案2】:

是的,想法似乎不错:

select min(ID), max(ID) from table into @min, @max;
set @range = @max - @min;
set @mr = @min + ((@range / 1000) * (rand() * 1000));
select ID from table
  where ID >= @mr and ID <= @mr + 1000
  order by rand()
  limit 1
--   into @result
;

可以根据需要将 1000 更改为 10000 或其他任何值...

编辑:你也可以试试这个:

select ID from table
  where (ID % 1000) = floor(rand() * 1000)
  order by rand()
  limit 1
;

将它沿不同的线分割...

编辑 2:

见:What is the best way to pick a random row from a table in MySQL?

这可能是最快的方法:

select @row := floor(count(*) * rand()) from some_tbl;
select some_ID from some_tbl limit @row, 1;

不幸的是,变量不能在限制子句中使用,因此您必须使用动态查询,或者在代码中编写查询字符串,或者使用 PREPARE 和 EXECUTE。此外,limit n, 1 仍然需要将 n 项扫描到表中,因此它的平均速度仅是上面列出的第二种方法的两倍左右。 (虽然它可能更统一并保证始终找到匹配的行)

【讨论】:

  • 我运行了这个查询,但它返回了一个空集。
  • 如果有超过 1000 条记录的空白,可能会发生这种情况...您的 ID 分布情况如何?
【解决方案3】:
SELECT ID
    FROM YourTable
    ORDER BY RAND() LIMIT 1;

【讨论】:

  • 尝试对 600 万条记录运行此查询。它需要永远运行。
猜你喜欢
  • 1970-01-01
  • 2018-11-19
  • 1970-01-01
  • 1970-01-01
  • 2010-09-17
  • 1970-01-01
  • 2013-04-28
相关资源
最近更新 更多