2015-10-22 4 views
-1

Так что у меня возникают проблемы с приложением, которое я разрабатываю в eclipse. В настоящее время у меня есть 2 файла, где он загружает все данные из файлов в базу данных SQL. Я обрабатываю это через многопоточность, где оба файла заселяются одновременно в базе данных и делают это относительно быстро. Общее количество записей в итоге составляет примерно 12 миллионов.Ускорьте процесс SQL-запроса и извлечения данных - Java

После заполнения SQL-запрос запускается в коде, где я хочу, чтобы мои записи в определенном порядке, однако, запуск этого SQL-кода в Java заканчивается тем, что занимает некоторое серьезное время (примерно 35 минут или больше для простого выполнения) прежде чем он начнет сбрасывать данные. Конечно, это связано с большим объемом данных, но есть ли способ сохранить заказ и сбросить данные в кусках или каким-то образом или каким-то образом улучшить SQL, или буквально каким-либо образом ускорить это приложение?

package fedMerger; 

//PREREQUISITES: ENSURE THE FOLLOWING ARE NOT DISABLED IN SERVICES MANAGEMENT WHEN RUNNING THIS UTILITY: 
//SQL SERVER BROWER 
//SQL SERVER 
//SQL SERVER VSS WRITER 

//BENCHMARK TEST v1 - 11million merged in 77 minutes - no multi threading 
//BENCHMARK TEST v2 - 11million merged in minutes - using multi threading 

import java.io.BufferedReader; 
import java.io.BufferedWriter; 
import java.io.FileNotFoundException; 
import java.io.FileReader; 
import java.io.FileWriter; 
import java.io.IOException; 
import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.sql.SQLException; 
import java.util.Scanner; 
import java.util.concurrent.TimeUnit; 

public class FedMerger2 extends Thread { 

    private static String directory = "C:\\Users\\xxx\\Desktop\\Files\\"; 
    private static String AgentfileName = "file1.txt"; 
    private static String otherFileName = "file.txt"; 
    public static Connection connection; 
    private static String mapperValue = ""; 
    private static String TimeStampTableName = "TimeStampTable"; 
    private static String timeStampColumn = "TIMESTAMP"; 
    private static String remainingDataColumn = "REMAINING"; 
    private static String user = "sa"; 
    private static String pass = "xxx"; 
    public static long timer; 
    public static String Timestampquery = "INSERT INTO " + TimeStampTableName + "(" + timeStampColumn + "," 
      + remainingDataColumn + ") VALUES (?,?)"; 
    public static String dbURL = "jdbc:sqlserver://localhost\\SQLExpress;database=TIMESTAMP_ORGANISER;integratedSecurity=true"; 

    public static void main(String[] args) throws Exception { 
     Connection conn = null; 
     timer = System.currentTimeMillis(); 
     conn = DriverManager.getConnection(dbURL, user, pass); 
     connection = conn; 
     String createTimeStampTable = "CREATE TABLE " + TimeStampTableName + "(" + timeStampColumn + " varchar(max)," 
       + remainingDataColumn + " varchar(max))"; 
     System.out.println("Tables & Columns created - Populating data..."); 
     conn.createStatement().executeUpdate(createTimeStampTable); 
    Thread t1 = new Thread(){ 
     @Override 
     public void run() 
     { 
      Connection conn = connection; 
      String mapperValue2 = ""; 
      int i = 0; 
      int records = 0; 
      try { 
       BufferedReader agentFile = new BufferedReader(new FileReader(directory + AgentfileName)); 
       PreparedStatement statement = null; 
       statement = conn.prepareStatement(Timestampquery); 
       for (mapperValue2 = agentFile.readLine(); mapperValue2 != null; mapperValue2 = agentFile.readLine()) { 
        i++; 
        records++; 
        if (!mapperValue2.isEmpty() && mapperValue2.length() > 5) { 
         statement.setString(1, mapperValue2.substring(0, 26)); 
         statement.setString(2, mapperValue2.substring(26, mapperValue2.length())); 
         statement.addBatch(); 
        } else {// ignore blanks or white spaces 
         System.out.println("blank found - skipped"); 
        } 
        if (i == 2500) {// Populating 100000 records at a time 
         System.out.println("executing Agent - " + records + " records..."); 
         statement.executeBatch(); 
         statement.clearBatch(); 
         i = 0; 
        } 
       } 
       System.out.println("executing Agent - " + records + " records..."); 
       statement.executeBatch(); 
       statement.close(); 
       agentFile.close(); 

      } catch (SQLException | FileNotFoundException ex) { 
       ex.printStackTrace(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
     }; 

     Thread t2 = new Thread(){ 
     @Override 
     public void run() 
     { 
      Connection conn = connection; 
      try {// Database setup and file to be read. 
       BufferedReader timeStampFile = new BufferedReader(new FileReader(directory + otherFileName)); 
       int i = 0; 
       int records = 0; 
       PreparedStatement ps = conn.prepareStatement(Timestampquery); 
       // Dump FED info onto SQL 
       for (mapperValue = timeStampFile.readLine(); mapperValue != null; mapperValue = timeStampFile.readLine()) { 
        i++; 
        records++; 
        if (!mapperValue.isEmpty() && mapperValue.length() > 5) { 
         ps.setString(1, mapperValue.substring(0, 26)); 
         ps.setString(2, mapperValue.substring(26, mapperValue.length())); 
         ps.addBatch(); 
        } else {// ignore blanks or white spaces 
         System.out.println("blank found - skipped"); 
        } 
        if (i == 2500) {// Populating 10000 records at a time 
         System.out.println("executing timestamp - " + records + " records..."); 
         ps.executeBatch(); 
         ps.clearBatch(); 
         i = 0; 
        } 
       } 
       System.out.println("executing final " + records + " records..."); 
       ps.executeBatch(); 
       ps.clearBatch(); 
       i = 0; 
       // Dump AGENT FED info into same SQL 
       System.out.print("Uploaded to database - Working SQL query"); 
       BufferedWriter writer = new BufferedWriter(new FileWriter(directory + "newfile" + "_MergedFinal.txt")); 
       // Organise accordingly 
       String retrieveData = "select " + timeStampColumn + "+" + remainingDataColumn + " as Data from " 
         + TimeStampTableName + " order by timestamp, case WHEN remaining LIKE '%agentStateEvent%' THEN -3 " 
         + "WHEN remaining LIKE '%TerminalConnectionCreated%' THEN -2 " + "ELSE -1 END"; 
       PreparedStatement stmt = conn.prepareStatement(retrieveData); 
       ResultSet result = null; 
       result = stmt.executeQuery(); 
       int j = 0; 
       String results = ""; 
       System.out.println("Data organised, ready to output..."); 
       while (result.next()) {// SQL Query ran - Output data line by line 
        j++; 
        System.out.println("outputing data - " + j); 
        results = result.getString("data"); 
        writer.write(results + "\r\n"); 
        writer.flush(); 
       } 
       writer.write(results + "\r\n"); 
       writer.flush(); 
       writer.close(); 
       System.out.println("Done - View at " + directory + "NewFile_MergedFinal.txt"); 
       conn.createStatement().executeUpdate("DROP TABLE " + TimeStampTableName); 
       conn.close(); 
       timeStampFile.close(); 
       System.out.print("Complete - Time taken: " + ((TimeUnit.MILLISECONDS.toMinutes(System.currentTimeMillis()) 
         - TimeUnit.MILLISECONDS.toMinutes(timer))) + " minutes"); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } catch (SQLException e) { 
       e.printStackTrace(); 
      } 
     } 
     }; 
     //multi thread running. 
     t1.start(); 
     t2.start(); 
    } 
} 
+0

Драйвер Microsoft JDBC-буфера _complete_ результата в памяти до 'ExecuteQuery()' возвращается к вызывающему абоненту. Добавьте параметр '; selectMethod = cursor' к URL-адресу JDBC, чтобы избежать этого, и убедитесь, что это улучшает ситуацию. –

+0

В дополнение к вышесказанному, я бы предположил, что ваша база данных не индексируется по столбцам, которые вы заказываете – tddmonkey

+0

, за ваши ответы. Попытайтесь выбрать метод select и отчитаться. К сожалению, havent был проиндексирован, к сожалению, –

ответ

1

Прежде всего, вам нужен правильный указатель на where where всех столбцов запроса.

Во-вторых, вы можете использовать некоторую встроенную утилиту для ускорения передачи данных. Пример как BCP утилита

declare @sql varchar(8000) 
select @sql = 'bcp "select * from EmailVarification..tblTransaction"  queryout c:\bcp\Tom.xls -c -t, -T -S' + @@servername 


exec master..xp_cmdshell @sql