多线程读取重复数据入库java_java-多线程数据库读取

本文讨论了在处理大量数据时,如何通过多线程和数据库存储过程优化读取性能。文章指出,网络和磁盘性能是关键因素,建议检查硬盘负载并考虑使用SSD或RAID。对于数据分片,rowid和rownum可能不是最佳选择,建议使用自定义分片列以确保线程间负载均衡。同时,注意数据库锁定模式对多线程的影响,以及查询优化的重要性。
摘要由CSDN通过智能技术生成

网络

首先,由于无论如何使用rowid和rownum是供应商锁定的,因此您应该考虑使用数据库存储的例程.它可以显着减少将数据从数据库传输到应用程序服务器的开销(特别是如果它们位于不同的计算机上并通过网络连接).

考虑到您有8000万条记录要传输,这可能对您来说是最好的性能提升,尽管它取决于线程所做的工作.

显然,增加带宽也将有助于解决网络问题.

磁盘性能

在更改代码之前,请在任务运行时检查硬盘驱动器负载,也许它只是不能处理那么多的I / O(同时读取10个线程).

迁移到SSD / RAID或群集数据库可能会解决此问题.在这种情况下,更改访问数据库的方式不会.

多线程可以解决CPU问题,但是数据库主要依赖于磁盘系统.

行号

如果要使用rowid和rownum实现它,可能会遇到几个问题.

1)rownum是为每个查询的结果动态生成的.因此,如果查询没有显式

排序,并且每次运行查询时某些记录可能具有不同的行编号.

例如,您第一次运行它并获得如下结果:

some_column | rownum

____________|________

A | 1

B | 2

C | 3

然后您第二次运行它,因为您没有显式排序,所以dbms(出于某种已知的原因)决定返回如下结果:

some_column | rownum

____________|________

C | 1

A | 2

B | 3

2)第一点还意味着,如果要对rownum进行过滤,它将生成包含所有结果的临时表,然后对其进行过滤

因此,rownum不是拆分结果的好选择.尽管rowid看起来更好,但它也存在一些问题.

罗威德

如果查看ROWID description,您可能会注意到“行值唯一地标识数据库中的一行”.

因此,当您删除一行时,在rowid序列中会有一个“洞”,因此rowid在表记录之间的分配可能不均等.

因此,例如,如果您有三个线程,每个线程都提取1’000’000个rowid,则有可能一个线程获得1’000’000条记录,而另外两个则分别获得1条记录.因此,一个将不堪重负,而另外两个则将挨饿.

在您的情况下,这可能没什么大不了的,尽管这很可能是您当前使用主键模式所面临的问题.

或者,如果您首先在调度程序中获取所有rowid,然后将它们平均分配(如peter.petrov建议),那么可以做到这一点,尽管获取8000万id听起来仍然很多,但我认为最好用一个进行拆分返回块边界的sql-query.

或者,您可以通过为每个任务提供少量的Rowid并使用Java 7中引入的Fork-Join框架来解决该问题,但是它是should be used carefully.

同样明显的一点是:rownum和rowid都不能跨数据库移植.

因此,拥有自己的“分片”列会更好,但随后您必须确保自己将记录分成大致相等的块.

还请记住,如果要在多个线程中执行此操作,则检查数据库使用的锁定模式很重要,也许它只是为每次访问锁定表,那么多线程是没有意义的.

正如其他人所建议的那样,您最好首先找到性能低下的主要原因(网络,磁盘,数据库锁定,线程匮乏,或者您只是次优查询-检查查询计划).

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值