我们有一个每周生成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);
}
答案 0 :(得分:2)
您可以尝试使用Oracle的DBMS_RANDOM.VALUE( low, high )
函数在数据库中完成所有操作:
Oracle安装程序:
var members = Object.keys($scope.members);
for (i = 0; i < members.length; i++) {
if (Object.keys($scope.members[members[i]]).length <= 2) { // Check key length of the existing keys only.
$scope.person[members[i]].isRequired = true;
}
}
插入强>:
CREATE TABLE randomValues (
rnd NUMBER(11,0) PRIMARY KEY
);
这是在100到140秒之间插入1,000,000行。
您可以删除循环并将代码简化为:
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;
/
然而,我做过的测试数量很少,这大约是200秒插入1,000,000行。