使用数据库表

时间:2016-05-17 08:50:56

标签: java oracle

我们有一个每周生成1000万个随机数的过程,并将它们存储在数据库表(Oracle)中。 我们有以下逻辑来创建给定范围的随机数。我们正在使用先前生成的数字保持生成数字的严格唯一性 (已经在db表中)。我们通过索引表列来实现这一点,该列存储随机数并在插入表时捕获异常 (如果发生异常,则重新生成随机数)。完成此过程大约需要1天,并继续增加所需的处理时间。

请帮助我们解决以下问题,以提高此过程的效果。

  1. 任何可能的方法来改进我们的随机数生成算法?
  2. 改善数据库操作的任何可能性
  3. 我们尝试的事情: 我们已经尽可能地清除表数据。 批量插入(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);
    }
    

1 个答案:

答案 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行。