首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >用数据库表生成唯一随机数

用数据库表生成唯一随机数
EN

Stack Overflow用户
提问于 2016-05-17 00:50:56
回答 1查看 1.4K关注 0票数 1

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

请帮助我们在下面的查询,以提高这一过程的性能。

  1. 有没有可能改进我们的随机数生成算法?
  2. 改进数据库操作的任何可能性

我们尝试过的事情:我们已经尽可能多地清除表数据。表中的批处理插入(2500条记录)将处理时间增加到3-4天,因为每个异常都导致重新创建每批数字。我们正在评估并行处理,以获得一些改进。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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);
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-05-17 01:51:21

您可以尝试使用Oracle的DBMS_RANDOM.VALUE( low, high )函数在数据库中完成所有操作:

Oracle安装

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE TABLE randomValues (
  rnd NUMBER(11,0) PRIMARY KEY
);

插入

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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行.

您可以删除循环并将代码简化为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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行。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37271376

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文