我们有一个每周生成1000万个随机数的过程,并将它们存储在数据库表(Oracle)中。我们有下面的逻辑来创建具有给定范围的随机数。我们用以前生成的数字(已经在db表中)来保持生成数的严格唯一性。我们通过索引表列实现了这一点,该列存储随机数,并在插入表时捕获异常(在异常情况下重新生成随机数)。完成这一过程几乎需要1天,并继续增加处理所需的时间。
请帮助我们在下面的查询,以提高这一过程的性能。
我们尝试过的事情:我们已经尽可能多地清除表数据。表中的批处理插入(2500条记录)将处理时间增加到3-4天,因为每个异常都导致重新创建每批数字。我们正在评估并行处理,以获得一些改进。
int itemsInPack = 10000000;
int pinLength = 10;
int randomSeedByteCount = 10;
long lowerRangeValue = (long) Math.pow(10.0, (double) (pinLength - 1));
long higherRangeValue = 10 * lowerRangeValue;
long numberRange = higherRangeValue - lowerRangeValue;
SecureRandom secureRandomNumberGen = SecureRandom.getInstance("SHA1PRNG");
byte[] bytes = new byte[1024 / 8];
secureRandomNumberGen.nextBytes(bytes);
byte[] seed = secureRandomNumberGen.generateSeed(randomSeedByteCount);
secureRandomNumberGen.setSeed(seed);
for(int k=0;k<itemsInPack;k++){
double nextDouble = secureRandomNumberGen.nextDouble();
long fraction = (long)(numberRange * nextDouble);
long pinNumber = (long)(fraction + lowerRangeValue);//Insert this to table
System.out.println("pinNumber: " + pinNumber);
}
发布于 2016-05-17 01:51:21
您可以尝试使用Oracle的DBMS_RANDOM.VALUE( low, high )
函数在数据库中完成所有操作:
Oracle安装
CREATE TABLE randomValues (
rnd NUMBER(11,0) PRIMARY KEY
);
插入
DECLARE
batchSize NUMBER(4,0) := 2500;
numRows NUMBER(8,0) := 1000000;
BEGIN
FOR i IN 1 .. numRows LOOP
INSERT INTO randomValues
SELECT rnd
FROM (
SELECT DISTINCT
FLOOR(
DBMS_RANDOM.VALUE(
POWER( 10, 10 ),
POWER( 10, 11 )
)
) AS rnd
FROM DUAL
CONNECT BY ROWNUM <= batchSize * 1.1
) r
WHERE ROWNUM <= batchSize
AND NOT EXISTS ( SELECT 'X'
FROM randomValues e
WHERE e.rnd = r.rnd );
END LOOP;
END;
/
这是在100-140秒内插入1,000,000行.
您可以删除循环并将代码简化为:
INSERT INTO randomValues
SELECT rnd
FROM (
SELECT DISTINCT
FLOOR(
DBMS_RANDOM.VALUE(
POWER( 10, 10 ),
POWER( 10, 11 )
)
) AS rnd
FROM DUAL
CONNECT BY ROWNUM <= :numRows * 1.1
) r
WHERE ROWNUM <= :numRows
AND NOT EXISTS ( SELECT 'X'
FROM randomValues e
WHERE e.rnd = r.rnd );
然而,我已经做过的少量测试,这是需要大约。200秒以插入1,000,000行。
https://stackoverflow.com/questions/37271376
复制相似问题