大数据量面试题求解

linuxlsx 2010-11-09 08:30:37
现在有一亿条数据,根据主键ID区分。现在要从中随机的选择100w条数据,要保证效率和随机性,同时一条数据只能取一次。有什么好的思路或者算法没?
...全文
419 24 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
梦之翼-凯 2010-11-11
  • 打赏
  • 举报
回复
路过学习了!帮顶起来!
taotie1225 2010-11-11
  • 打赏
  • 举报
回复
还有比二楼的更好的法子?
linuxlsx 2010-11-11
  • 打赏
  • 举报
回复
在等两天,如果没有更好的答案就结贴给分了
kingkingzhu 2010-11-10
  • 打赏
  • 举报
回复
hash 100个分区出来
每次查一个 哈哈
kingkingzhu 2010-11-10
  • 打赏
  • 举报
回复
select * from tb sample(20) where rownum<=1000000
1亿=100个100w
每次采样1 就够了 但这里采样20% 然后取100w
会不会取到重复的啊
心中的彩虹 2010-11-10
  • 打赏
  • 举报
回复
[Quote=引用楼主 lsxjl 的回复:]
现在有一亿条数据,根据主键ID区分。现在要从中随机的选择100w条数据,要保证效率和随机性,同时一条数据只能取一次。有什么好的思路或者算法没?
[/Quote]
select *
from (select * from tb order by dbms_random.value) where rownum<=1000000

估计最好的方法也就使用采样表扫描
select * from tb sample(20) where rownum<=1000000
zkl516321905 2010-11-10
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 lsxjl 的回复:]
使用随机函数的话, 会有重复的问题。这里一条数据最多取一次。不知道怎么处理重复取同一条数据的问题
[/Quote]

可以先将随机的数据放入一个临时表,然后下次随机的时候再去检索一下临时表的数据,取没取过的,不过这样子,你数据量大,性能是个问题。
feixianxxx 2010-11-10
  • 打赏
  • 举报
回复
学习了...
linuxlsx 2010-11-10
  • 打赏
  • 举报
回复
使用随机函数的话, 会有重复的问题。这里一条数据最多取一次。不知道怎么处理重复取同一条数据的问题
碧水幽幽泉 2010-11-09
  • 打赏
  • 举报
回复
4.5要改下:

--4.sample(1) 按百分比
select * from(select * from table_name sample(1)) where rownum <= 1000000;
--5.sample block(1) 按数据块
select * from(select * from table_name sample block(1)) where rownum <= 1000000;
碧水幽幽泉 2010-11-09
  • 打赏
  • 举报
回复

--从一个表中随机取100W条记录的5种方法
--1.dbms_random.value
select * from(select * from t_ums_config order by dbms_random.value) where rownum <= 1000000;
--2.dbms_random.random
select * from(select * from table_name fig order by dbms_random.random) where rownum <= 1000000;
--3.sys_guid()
select * from(select * from table_name order by sys_guid()) where rownum <= 1000000;
--4.sample(20) 按百分比
select * from(select * from table_name sample(20)) where rownum <= 1000000;
--5.sample block(20) 按数据块
select * from(select * from table_name sample block(20)) where rownum <= 1000000;

4.5效率相对好些!
javaANDcobol 2010-11-09
  • 打赏
  • 举报
回复
select a.title, a.type
from (
select row_number() over(partition by a1.title order by sys_guid()) rcn, a1.title, a1.type
from a a1 ) a
where a.rcn<1000000;
此处,将title换为ID即可


推荐一下这个,sys_guid()可以生成32位序列号 每次生成不一样 可以用过表主键值,据说效益比sequence更高!
wangyuzx1985 2010-11-09
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 tangren 的回复:]
1、如果ID有规则,且可以重新生成,则可以据此规律生成一个包含100万个ID记录的表,然后关联取出数据,最后记录可通过create table as 的方式生成放入临时表中。
2、使用数据块采样的方式,避免全表扫描会更快。先计算采样的百分比。如:1百万/1亿=1%最后使用如下语句(当然采样1%数据块可能不是刚好一百万数据,如果少可以增加一点百分比,如果多于则使用rownum限制):
creat……
[/Quote]

这个方法好。 第2种
javaANDcobol 2010-11-09
  • 打赏
  • 举报
回复
Id既然是主键,那么直接取随机的id不就可以了吗?
feixianxxx 2010-11-09
  • 打赏
  • 举报
回复
帮顶 期待好方法

数据量很大 保证效率有点难度
一般的随机函数肯定慢
tangren 2010-11-09
  • 打赏
  • 举报
回复
当然,最后在t_tmp后加上nologging减少重做日志产生。
tangren 2010-11-09
  • 打赏
  • 举报
回复
1、如果ID有规则,且可以重新生成,则可以据此规律生成一个包含100万个ID记录的表,然后关联取出数据,最后记录可通过create table as 的方式生成放入临时表中。
2、使用数据块采样的方式,避免全表扫描会更快。先计算采样的百分比。如:1百万/1亿=1%最后使用如下语句(当然采样1%数据块可能不是刚好一百万数据,如果少可以增加一点百分比,如果多于则使用rownum限制):
create table t_tmp as select * from t_sr_servicerequest sample block(1) where rownum<1000000;
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 java3344520 的回复:]
最快的方法,根据ROWID来取

至于其他考虑细节,自己想想吧,呵呵
[/Quote]我第一想法也是rowid 但是觉得rowid没什么规律
不知道杨兄有什么好的方法
iqlife 2010-11-09
  • 打赏
  • 举报
回复
最快的方法,根据ROWID来取

至于其他考虑细节,自己想想吧,呵呵
iihero 2010-11-09
  • 打赏
  • 举报
回复
select a.title, a.type
from (
select row_number() over(partition by a1.title order by sys_guid()) rcn, a1.title, a1.type
from a a1 ) a
where a.rcn<1000000;
此处,将title换为ID即可
加载更多回复(1)

17,382

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 基础和管理
社区管理员
  • 基础和管理社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧