2

我的数据库中有一个大表(可能有数百万条记录),我需要选择 #X 个随机行(假设 #X 在 10 到 50 之间),但我需要这个查询尽可能优化。

该表如下所示:

CREATE TABLE sample (
    id bigint auto_increment PRIMARY KEY,
    user_id bigint NOT NULL,
    screen_name VARCHAR NOT NULL,
    ...
);

我四处寻找,我找到了这样的答案:

SELECT * FROM sample ORDER BY RAND() limit X.

但在我看来,这将获取完整的表格然后对其进行排序,不是吗?

我认为最好生成 10 或 50 个随机整数并执行select * from sample where rowid in (<random integer list>). 但是 afaik,H2 中缺少 rowid 概念,所以我可能会选择在我的表中使用 ID 列。

如果我能用一个 SQL 查询来完成这项任务,那就太棒了。

有更好的建议吗?

4

4 回答 4

3

以下脚本非常有效地选择每 n 行。它假设 id 中没有间隙。如果可能存在间隙,那么您可能希望将 range(1, 100) 增加到 range(1, 200) 左右。要获得随机行,最后的公式需要稍作更改:

drop table test;

create table test(
  id bigint auto_increment primary key, 
  name varchar(255));

insert into test 
select x, 'Hello ' || x from system_range(50, 1200);

select * from test t, system_range(1, 100) range
where t.id = x * (select max(id)-min(id) from test) / 100 + 
(select min(id) from test);
于 2013-01-14T12:55:35.547 回答
2

您应该使用 columnid而不是rowid. 列id存在于您的表中并且是auto_increment.

于 2013-01-14T10:20:46.343 回答
0

您可以对表进行排名并从中选择 50 个随机排名,避免以任何方式进行排序或分组以保持优化。

于 2015-12-09T14:16:41.650 回答
0

我为此做的是创建一个临时表。在表中生成从 1 到最大标识值的随机数。然后从他们的身份值在临时表中的表中选择。

“这样做的单一查询方式”

创建临时表(我不知道它的 h2 语法,但它支持字段名称为 DesiredIdentity 的临时表)

从表中选择最大标识值。

使用 rand 命令循环将随机数插入到临时表中,从 1 到所需的随机行数。将随机范围设置为 1 到最大行数。确保不选择相同的随机数。

然后从身份临时表中身份值所在的表中进行选择。

于 2017-07-11T21:12:45.107 回答