【问题标题】:How to Read Large data from database using java?如何使用java从数据库中读取大数据?
【发布时间】:2020-12-21 12:37:12
【问题描述】:

我的表中有超过 2gb 的数据我需要从单个表中读取更多的 1gb 数据,我知道 db 端可用的各种选项来实现这一点,但我需要在 java 代码中使用更好的方法,谁能告诉使用示例 java 代码,例如多线程中的并行处理。

示例代码

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
 
public class SelectRowsExample {
  
  public static void main(String[] args) {
 
    Connection connection = null;
    try {
 
  // Load the MySQL JDBC driver
 
  String driverName = "com.mysql.jdbc.Driver";
 
  Class.forName(driverName);
               
  String serverName = "localhost";
 
  String schema = "test";
 
  String url = "jdbc:mysql://" + serverName +  "/" + schema;
 
  String username = "username";
 
  String password = "password";
 
  connection = DriverManager.getConnection(url, username, password);
 
   
 
  System.out.println("Successfully Connected to the database!");
 
   
    } catch (ClassNotFoundException e) {
 
  System.out.println("Could not find the database driver " + e.getMessage());
    } catch (SQLException e) {
 
  System.out.println("Could not connect to the database " + e.getMessage());
    }
 
    try {
 
       
Statement statement = connection.createStatement();
 
ResultSet results = statement.executeQuery("SELECT * FROM employee orderby dept");
         
while (results.next()) {
   
  String empname = results.getString("name");
 
  System.out.println("Fetching data by column index for row " + results.getRow() + " : " + empname);
 
   String department = results.getString("department");
 
  System.out.println("Fetching data by column name for row " + results.getRow() + " : " + department);
 
 
}
 

        } catch (SQLException e) {
 
  System.out.println("Could not retrieve data from the database " + e.getMessage());
    }
 
  }
}

在这里,我的查询将返回姓名和部门详细信息,每个部门都会有 1gb 的数据。如果我使用这种方式,它会降低应用程序的速度。这就是为什么我想在多线程中进行并行处理。任何人都请给我快速读取大量数据的建议。

【问题讨论】:

  • 是什么让您认为并行处理或多线程会在这里有所改进?您当前从数据库读取的代码是什么,它太慢了?您的目标速度是多少,您的 Java 应用程序在什么硬件上运行,服务器在什么硬件上运行?等等……
  • @luk2302 我正在寻找更好的方法来做到这一点。如果我尝试正常读取超过 1 GB 的数据,则会影响应用程序的性能。
  • 不,不会。什么是“正常”?
  • 没有。除非您非常清楚说明您要达到的性能,否则一开始就没有性能问题。 “性能问题”是一个很好的流行词,它本身绝对没有任何意义。
  • “如果我使用这种方式,它会明显降低应用程序的速度” - 那又如何?你的用例是什么,你的要求是什么?请注意,1gb 的数据是微不足道的。如果您读取 1TB 的数据,您可能会遇到麻烦。在这两种情况下,java 都无法单独解决问题,它取决于数据库、网络、硬件等。您没有提供任何上下文。

标签: java database multithreading parallel-processing


【解决方案1】:

在您的示例中,您不必使用像并行这样的大口径枪。此外,它不一定能解决您的问题,因为 luk2302 提到的硬件、网络等原因可能存在很多瓶颈。

有两个更简单的调整:

  • 仅选择您真正需要的数据。即使您的员工记录有 3 列,您也可以节省 1/3 的数据,从而提高速度并降低内存消耗。更不用说它是否有更多的列。
ResultSet results = statement.executeQuery("SELECT name, department FROM employee orderby dept");
  • 默认的 fetchSize 是不够的。它的值取决于驱动程序,但例如默认情况下,当 Oracle JDBC 运行查询时,它一次从数据库游标中检索 10 行的结果集。我知道您使用的是 MySql,但应该差不多。增加它可以减少对数据库游标的总行程计数,这是昂贵的。因此,我建议将其增加到 500 或 1000,但您甚至可以尝试更高的值。有关 fetchSize 的更多信息:What does Statement.setFetchSize(nSize) method really do in SQL Server JDBC driver?
Statement statement = connection.createStatement();
statement.setFetchSize(1000);
  • +1 - System.out.println 也会减慢您的代码速度。您可以在此处阅读:Why is System.out.println so slow? 但最好用记录器库替换,或者至少出于测试目的,您可以使用以下内容:
if(results.getRow()%1000 == 0) {
    System.out.println("Fetching data by column index for row " + results.getRow() + " : " + empname);
}

兄弟, 南多尔

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-26
    • 1970-01-01
    • 2016-05-01
    相关资源
    最近更新 更多