Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将一个表中的数百万行与另一个表中的数百万行进行比较的最快方法_Java_Database_Oracle_Performance_Optimization - Fatal编程技术网

Java 将一个表中的数百万行与另一个表中的数百万行进行比较的最快方法

Java 将一个表中的数百万行与另一个表中的数百万行进行比较的最快方法,java,database,oracle,performance,optimization,Java,Database,Oracle,Performance,Optimization,我想比较两个表,每个表中有数百万条记录,并从比较中获得匹配数据 为了从两个表中获得匹配数据,我们首先比较表1中的名称不应等于表2中的名称。然后我们比较表1中的城市应等于表2中的城市,最后我们比较表1中的出生日期应与表2中的出生日期在+-1年范围内 表1中的一行可以与表2中的数据有多个匹配项。 此外,对于每个匹配,我需要一个唯一的记录ID,单个表1行的多个匹配数据必须具有相同的唯一记录ID 我尝试使用Java代码和PL/SQL过程,但这两个过程都需要几个小时,因为这涉及到数百万数据与数百万数据的比

我想比较两个表,每个表中有数百万条记录,并从比较中获得匹配数据

为了从两个表中获得匹配数据,我们首先比较
表1
中的名称不应等于
表2
中的名称。然后我们比较
表1中的城市
应等于
表2中的城市
,最后我们比较
表1中的出生日期
应与
表2中的出生日期
在+-1年范围内

表1
中的一行可以与
表2中的数据有多个匹配项。
此外,对于每个匹配,我需要一个唯一的记录ID,单个表1行的多个匹配数据必须具有相同的唯一记录ID


我尝试使用Java代码和PL/SQL过程,但这两个过程都需要几个小时,因为这涉及到数百万数据与数百万数据的比较。有没有更快的方法进行匹配?

从两个表中选择数据,按关键字段排序,然后并行迭代并比较。比较时间应该很快,所以总运行时间应该只比每个有序查询的运行时间之和略多


更新

显示需要数据的部分交叉联接:

left.name <> right.name
left.city = right.city
abs(left.birthDate - right.birthDate) <= 1 year
  • 迭代记录并跳过具有相同
    名称的记录。这些是与给定记录“匹配”的
    left
    记录

    • 如果需要,可以将其展平,并使用流过滤名称:

      List<Person> matches = coll.stream()
              .flatMap(List::stream)
              .filter(p -> ! p.name.equals(right.name))
              .collect(Collectors.toList());
      
      List matches=coll.stream()
      .flatMap(列表::流)
      .filter(p->!p.name.equals(right.name))
      .collect(Collectors.toList());
      
      可选地用实际处理逻辑替换
      collect()

  • 如步骤4所述处理完区块后,即当您看到下一个
    城市
    时,清除
    树状图
    ,并从步骤3开始重复下一个区块,即
    城市

  • 这种逻辑的优点:

    • 数据只从数据库服务器发送一次,即从相对较慢的数据链路中消除了部分交叉连接导致的数据重复

    • 如果需要,这两个查询可以来自两个不同的数据库

    • 通过一次只保留一个查询的
      城市
      (左侧的
      )的数据,可以减少内存占用

    • 如果需要,匹配逻辑可以是多线程的,以获得额外的性能,例如

    • 线程1将
      left
      区块加载到
      TreeMap
      ,并将其交给线程2进行处理,而线程1开始加载下一个区块

    • 线程2通过调用
      subMap()
      ,迭代subMap,将匹配的
      记录交给线程3处理,从而迭代
      并查找匹配的记录

    • 线程3处理匹配对


    从两个表中选择数据,按关键字段排序,然后并行迭代并比较。比较时间应该很快,所以总运行时间应该只比每个有序查询的运行时间之和略多


    更新

    显示需要数据的部分交叉联接:

    left.name <> right.name
    left.city = right.city
    abs(left.birthDate - right.birthDate) <= 1 year
    
  • 迭代记录并跳过具有相同
    名称的记录。这些是与给定记录“匹配”的
    left
    记录

    • 如果需要,可以将其展平,并使用流过滤名称:

      List<Person> matches = coll.stream()
              .flatMap(List::stream)
              .filter(p -> ! p.name.equals(right.name))
              .collect(Collectors.toList());
      
      List matches=coll.stream()
      .flatMap(列表::流)
      .filter(p->!p.name.equals(right.name))
      .collect(Collectors.toList());
      
      可选地用实际处理逻辑替换
      collect()

  • 如步骤4所述处理完区块后,即当您看到下一个
    城市
    时,清除
    树状图
    ,并从步骤3开始重复下一个区块,即
    城市

  • 这种逻辑的优点:

    • 数据只从数据库服务器发送一次,即从相对较慢的数据链路中消除了部分交叉连接导致的数据重复

    • 如果需要,这两个查询可以来自两个不同的数据库

    • 通过一次只保留一个查询的
      城市
      (左侧的
      )的数据,可以减少内存占用

    • 如果需要,匹配逻辑可以是多线程的,以获得额外的性能,例如

    • 线程1将
      left
      区块加载到
      TreeMap
      ,并将其交给线程2进行处理,而线程1开始加载下一个区块

    • 线程2通过调用
      subMap()
      ,迭代subMap,将匹配的
      记录交给线程3处理,从而迭代
      并查找匹配的记录

    • 线程3处理匹配对

    “我尝试使用java,通过jdbc连接将两个表中的数据存储在列表中,然后用一个列表迭代另一个列表。但这非常缓慢,需要花费许多小时才能完成,甚至多次出现超时异常。”

    祝贺你。这是启蒙道路上的第一步。数据库在处理数据方面比Java好得多。Java是一种优秀的通用编程语言,但数据库针对关系数据处理进行了优化:它们只需更快地完成,CPU更少,内存更少,网络流量更少

    “我还为同样的问题创建了一个sql过程,这是一个更快的过程 比java程序还慢,但仍然需要很多时间(几个小时)才能完成 完成。”

    您即将进入启蒙的第二步:逐行处理(即程序迭代)很慢。SQL是
    select col1, col2, col3
    from huge_table_1
    MINUS
    select col1, col2, col3
    from huge_table_2
    
    select * from huge_table_1 ht1
    where exists
          ( select null from huge_table_2 ht2
            where ht2.city = ht1.city
            and ht1.date_of birth between add_months(ht2.date_of birth, -12) 
                                      and add_months(ht2.date_of birth, 12) 
            and ht2.name != ht1.name)
    /