多线程处理表数据性能问题 30
现有表A,存在100000条符合条件的数据,现在需要处理这些数据,逻辑为查出这些数据,然后处理后需要删除表A对应数据,同时插入表B,并且记录文件C现在我的方案以及做法1个...
现有表A,存在100000条符合条件的数据, 现在需要处理这些数据,逻辑为查出这些数据,然后处理后需要删除表A对应数据,同时插入表B,并且记录文件C
现在我的方案以及做法
1个查询线程分批查询这些数据到一个共享list 同时更新每批查出的数据的状态为X(正在操作,防止下一批数据查询时候重复),再起5个线程取这些数据,然后每个处理后批量删除表A对应取的数据,并且插入表B,并且写文件C
问题来了,代码写好后,测试发现功能无问题,可以正常实现,但是性能很差
因为一目了然,过多操作表A,因为查询需要更新状态(锁表) 每个线程需要删除数据(锁表),导致效率很差
暂时没有想到比较好的方法解决
补充之前考虑的方案2,分5个线程,在线程内查询并操作(没去实现,只是想法,应该也会存在这个问题)
个人考虑 如果能解决查询时候不更新状态 又能保证数据的唯一性,能提升一些性能,不知各位大大有何高见? 展开
现在我的方案以及做法
1个查询线程分批查询这些数据到一个共享list 同时更新每批查出的数据的状态为X(正在操作,防止下一批数据查询时候重复),再起5个线程取这些数据,然后每个处理后批量删除表A对应取的数据,并且插入表B,并且写文件C
问题来了,代码写好后,测试发现功能无问题,可以正常实现,但是性能很差
因为一目了然,过多操作表A,因为查询需要更新状态(锁表) 每个线程需要删除数据(锁表),导致效率很差
暂时没有想到比较好的方法解决
补充之前考虑的方案2,分5个线程,在线程内查询并操作(没去实现,只是想法,应该也会存在这个问题)
个人考虑 如果能解决查询时候不更新状态 又能保证数据的唯一性,能提升一些性能,不知各位大大有何高见? 展开
4个回答
展开全部
思路:一次加载部分A数据到内存,然后开启多个线程处理,处理的结果保存到内存,结果达到一定数量,写入B
1:加载A数据:A表单行数据平均占用空间大小1K,就加载1000条,总共也就1M左右,按照这个算法去加载,加载数量自行设定,一次数据库加载完毕保存到集合中List,作为源数据集合
2:开启多个线程,循环从源数据集合中取数据进行处理,处理结果保存到结果数据集合中,当结果数据集合数量达到1000(自行设定),暂停其他线程,写入数据到B,写入完毕清空结果数据集合后继续执行。当当前源数据集合中的数据库处理完毕,清空当前的源数据集合,继续从A表取数据保存到该集合中,直到A表没有数据为止
3:所有数据处理完毕,所有线程结束,如果结果数据集合中还有数据,继续写入到B表,执行写入C操作
4,清空A表
1:加载A数据:A表单行数据平均占用空间大小1K,就加载1000条,总共也就1M左右,按照这个算法去加载,加载数量自行设定,一次数据库加载完毕保存到集合中List,作为源数据集合
2:开启多个线程,循环从源数据集合中取数据进行处理,处理结果保存到结果数据集合中,当结果数据集合数量达到1000(自行设定),暂停其他线程,写入数据到B,写入完毕清空结果数据集合后继续执行。当当前源数据集合中的数据库处理完毕,清空当前的源数据集合,继续从A表取数据保存到该集合中,直到A表没有数据为止
3:所有数据处理完毕,所有线程结束,如果结果数据集合中还有数据,继续写入到B表,执行写入C操作
4,清空A表
追问
你的思路我认同 关键是处理后需要同步删除表A数据,所以给分批查询加载数据带来麻烦, 如查询1000条数据, 然后线程处理,后删除了500条 这个时候查询线程再去查询1000条 就会有重复数据了, 所以比较麻烦, 至于一次加载全部 不太科学,数据量大的话 如100000条 一次加载 需要的时间很长,不科学。
追答
第一: 我的思路在A表数据库处理完毕之前没有对A表进行修改操作
第二:我的操作是分批操作,分批读取A表操作
很多事情都是想复杂了
我原来按照这个思路,从数据库中读取用户名到网页中抓取数据进行处理之后保存到数据库
除了0.5%的超时玩,300W个用户ID,20多分钟采集完毕
展开全部
首先需要明确的是对于A表的操作肯定不能处理一条删一条,所以建议的方案是对数据进行多线程分段查询,然后记录下需要删除的A表中数据的ID。第二个,对于插入B表的操作,肯定有锁定的问题,所以建议先分开来插入,比如分成 B1,B2等等。第三个,对于文件的操作同第二点。
在这些全部做完后,一次性对A表做删除操作,将B1等等分表的数据一次性插入B表,文件合并
只有这样才能充分利用多线程,而又避开锁表的问题。
在这些全部做完后,一次性对A表做删除操作,将B1等等分表的数据一次性插入B表,文件合并
只有这样才能充分利用多线程,而又避开锁表的问题。
更多追问追答
追问
你的意思是分段查询数据 并且不更新为状态X, 分配给线程处理,写文件 插表,然后数据都处理完了再统一删除所以表A数据? 如果数据量大的话 这些都放在内存中 这样好吗?
追答
对的,因为每段线程拿到的数据是不重复的,所以不必标记。数据量大的话,你可以利用临时表操作不必全放在服务器内存里,我上面也提到的,关键是先分再合,性能就会提高了
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
你这里面存在一个事务的问题,所以一条一条处理肯定提高不了多少性能。所以多线程也不一定能解决。 如果不要求时效性,最好采用批量处理。如果是用Oracle数据库,那在数据库方面也要进行优化。
再者,我看你的操作都是数据库内部表数据库的转移,不知道你为什么要用外部程序来实现,我觉得可以用数据库存储过程来做,但具体不知道你的业务,所以可能有你的理由。
再者,我看你的操作都是数据库内部表数据库的转移,不知道你为什么要用外部程序来实现,我觉得可以用数据库存储过程来做,但具体不知道你的业务,所以可能有你的理由。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
数据库是支持多用户连接的。
嗯。你会查出十万条记录。
将这些分成五组。一个线程,一个连接,来操作这些数据不可以吗?
还有,不知道写入C的时候,要不要求顺序。如果要求顺序,多线程,好象无法保证。
嗯。你会查出十万条记录。
将这些分成五组。一个线程,一个连接,来操作这些数据不可以吗?
还有,不知道写入C的时候,要不要求顺序。如果要求顺序,多线程,好象无法保证。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询