免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3492 | 回复: 10
打印 上一主题 下一主题

对于千万级数据量的表,这种速度是否正常? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-03-25 22:55 |只看该作者 |倒序浏览
刚使用informix不久,最近需要对一个有1000万条记录的表进行操作,主要是这样的:原表主要字段是序列号(cust_id)和序号(seq_nbr),这两个字段作为主键,对于相同的序列号可以有多个序号。现在要新建一表,序列号(cust_id)作为主键,将原表中的数据插入新表中,对于相同的序列号,只取序号(seq_nbr)最大的那条记录。写了个存储过程来操作,结果一分钟只能插入几条数据,这样的速度是否正常?请问高手们改如何解决?

论坛徽章:
0
2 [报告]
发表于 2006-03-26 10:46 |只看该作者
把你的存储过程贴出来,让大伙瞧瞧。1分钟才几条记录,1000万条,岂不是要运行到5000年?

论坛徽章:
0
3 [报告]
发表于 2006-03-26 12:31 |只看该作者
直接写select语句会比这个快吧

论坛徽章:
0
4 [报告]
发表于 2006-03-26 12:47 |只看该作者
对于数据量较大的表,采取的方法有两种
1是使用本身的数据库运算
2是使用在内存中处理运算的方法

1
你这种情况可以改变一下流程
int tmp_cust_id = 0;

EXEC SQL DECLARE cur1 CURSOR FOR
        select cust_id,seq_nbr,..... FROM a ORDER BY seq_nbr;

EXEC SQL OPEN cur1;

while ( 1 ) {
     EXEC SQL FETCH cur1 INTO :stru_a;
     if ( SQLCODE )
           break;
     
     if ( stru_a.cust_id != tmp_cust_id ) {
           tmp_cust_id = stru_a.cust_id;
           EXEC SQL INSERT INTO b VALUES( :stru_a );
           if ( SQLCODE  )
                 printf( "INSERT ERROR!,SQLCODE = [%d]\n",SQLCODE );
     }
     memset( stru_a,0x00,sizeof(stru_a) );
}
EXEC SQL CLOSE cur1;
EXEC SQL FREE cur1;


还有就是使用内存运算处理,速度会更快

论坛徽章:
0
5 [报告]
发表于 2006-03-26 13:38 |只看该作者
肯定不正常,一般几分钟时间内就可以完成了:
insert into tab_b
select cust_id,max(seq_nbr) from tab_a group by 1;

论坛徽章:
0
6 [报告]
发表于 2006-03-26 22:09 |只看该作者
原帖由 sgool 于 2006-3-26 13:38 发表
肯定不正常,一般几分钟时间内就可以完成了:
insert into tab_b
select cust_id,max(seq_nbr) from tab_a group by 1;


如果只有这两个字段当然可以这样,关键是还有其他的数据字段需要插入。我的存储过程基本原理是这样:(tab_a 是原表,tab_b是临时表,tab_c是目标表)
insert into tab_b
select cust_id,max(seq_nbr)  seq_nbr  from tab_a group by cust_id; ----这一步很快,确实如楼上所说

foreach tab_b for select cust_id , seq_nbr  into  n_cust_id ,n_seq_nbr from tab_b
select * from tab_a into  column1,.......   where cust_id =n_cust_id and seq_nbr=n_seq_nbr;     -----关键是慢在这一步了
insert into tab_c  (........)  values  (........);
end foreach;

现在的问题是光select * from tab_a where cust_id =......;  就要花费几秒钟

[ 本帖最后由 knowmelj 于 2006-3-26 22:31 编辑 ]

论坛徽章:
0
7 [报告]
发表于 2006-03-27 08:24 |只看该作者
select * from tab_a into  column1,.......   where cust_id =n_cust_id and seq_nbr=n_seq_nbr;     -----关键是慢在这一步了

tab_a 有个索引 cust_id , seq_nbr 就不该慢的。

论坛徽章:
0
8 [报告]
发表于 2006-03-27 08:41 |只看该作者
select * from tab_a into  column1,.......   where cust_id =n_cust_id and seq_nbr=n_seq_nbr;     -----关键是慢在这一步了
insert into tab_c  (........)  values  (........);

这两句 可以合并
insert into tab_c select  * from  tab_a  where cust_id = n_cust_id and seq_nbr= n_seq_nbr;

或者把整个 foreach 循环 改成这样
先在tab_b 建个索引 tab_b_idx1(cust_id , seq_nbr )
insert into tab_c select a.* from tab_a a , tab_b b  
where a.cust_id = b.cust_id and a.seq_nbr =b.seq_nbr;

以上未经过测试,请楼主测试。

论坛徽章:
0
9 [报告]
发表于 2006-03-27 12:55 |只看该作者
informix 为主键建的索引是聚族索引还是普通的唯一索引?
现在按主键cust_id 来查询记录都要花费很长时间,是不是一定要用数据分片才能解决呢?

论坛徽章:
0
10 [报告]
发表于 2006-03-28 10:00 |只看该作者
原帖由 knowmelj 于 2006-3-25 22:55 发表
刚使用informix不久,最近需要对一个有1000万条记录的表进行操作,主要是这样的:原表主要字段是序列号(cust_id)和序号(seq_nbr),这两个字段作为主键,对于相同的序列号可以有多个序号。现在要新建一表,序列 ...


仅仅从题目来看的话,觉得你的存储过程写的有些奇怪,没大明白你的企图
如果仅仅是你 题目的意思,不就是 cust_id,seq_nbr做主键,把相对应的字段数据取出来放在新表里面而已
这样的话
直接
set pdqpriority 10;
Insert table_B (...........)
select cust_id ,max(seq_nbr),C,D,E.....
from table_A
group by cust_id,C,D,E..........
不就ok了?
每对应一个cust_id,seq_nbr,生成相应的c,d,e等。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP