简体   繁体   English

方法花费太长时间

[英]method takes too long

I wrote a method that gathers data from an Oracle server, formats and encrypts the data then inserts it into a MS SQL server. 我编写了一种方法,该方法从Oracle服务器收集数据,对数据进行格式化和加密,然后将其插入MS SQL服务器。 The method moves about 60000 records and takes a bit long and is a little sloppy. 该方法可移动约60000条记录,耗时长且有点草率。 Can anyone see places to clean it up and make it faster? 谁能看到清理它的地方并使其更快?

2 of the areas that I see might need improvements are when the result set is being added the the List. 我认为可能需要改进的两个领域是将结果集添加到列表中时。 And when the List is being inserted 1000 rows at a time into the MS SQL table. 当列表一次插入1000行到MS SQL表中时。

Here is the code: 这是代码:

public static void get_random_selection(Connection ora_conn, Connection sql_conn) throws Exception, SQLException{

    Statement sql_stmt = sql_conn.createStatement();
    Statement ora_stmt = ora_conn.createStatement();

    ResultSet sql_rs = null;
    ResultSet ora_rs = null;

    //Select the max QUARTER from RANDOM_SELECTION in MS SQL
    sql_rs = sql_stmt.executeQuery("SELECT MAX(QUARTER) FROM RANDOM_SELECTION");

    sql_rs.next();
    int max_from_mssql = sql_rs.getInt(1);

    ora_rs = ora_stmt.executeQuery("SELECT MAX(QUARTER) FROM RANDOM_SELECTION");

    ora_rs.next();
    int max_from_oracle = ora_rs.getInt(1);

    //If the max_from_oracle is larger than max_from_mssql than the AL's and RL's in Oracle
    //are fresher and need to be moved to MS SQL
    //if (max_from_oracle > max_from_mssql){
    if(1==1){

        System.out.println("The RANDOM_SELECTION table in Oracle is more up to date than the RANDOM_SELECTION table in MS SQL.");

        System.out.println("Retrieving RANDOM_SELECTION data from Oracle.");

        //select items from RANDOM_SELECTION and DROPPER_CITY_BRK_2 that need to be moved
        ora_rs = ora_stmt.executeQuery("select distinct(random_selection.randnum), " 
                            + "random_selection.quarter, " 
                            + "random_selection.ozip3, "
                            + "random_selection.boxid, " 
                            + "random_selection.boxaddr, " 
                            + "random_selection.locdesc, " 
                            + "random_selection.loccity, " 
                            + "random_selection.lastmf, "
                            + "random_selection.lastsat, "
                            + "random_selection.boxtype, "
                            + "random_selection.svcclas, "
                            + "random_selection.dropzip5, "
                            + "random_selection.dropper_id "
                      + "from random_selection "
                      + "where random_selection.dropper_id is not null "
                      + "and random_selection.quarter = " + max_from_oracle + " "

                  + "union "

                      + "select distinct(random_selection.randnum), "
                            + "random_selection.quarter, " 
                            + "random_selection.ozip3, "
                            + "random_selection.boxid, " 
                            + "random_selection.boxaddr, " 
                            + "random_selection.locdesc, " 
                            + "random_selection.loccity, " 
                            + "random_selection.lastmf, "
                            + "random_selection.lastsat, "
                            + "random_selection.boxtype, "
                            + "random_selection.svcclas, "
                            + "random_selection.dropzip5, "
                            + "dropper_city_brk_2.dropper_id "
                      + "from random_selection, dropper_city_brk_2, dropper "
                      + "where random_selection.ozip3 = dropper_city_brk_2.zip3 "
                      + "and dropper.dropper_id = dropper_city_brk_2.dropper_id "
                      + "and dropper.active = 1 "
                      + "and dropper_city_brk_2.dropper_id <> 10002 "
                      + "and random_selection.quarter = " + max_from_oracle + " "
                      + "and random_selection.dropper_id is null");

        System.out.println("Retrieved RANDOM_SELECTION data from Oracle.");

        List<String[]> random_selection = new ArrayList<String[]>();

        System.out.println("Assigning ResultSet to List.");

        while (ora_rs.next()){
            random_selection.add(new String[]{
                ora_rs.getString("RANDNUM"),
                ora_rs.getString("QUARTER"),
                ora_rs.getString("OZIP3"),
                ora_rs.getString("BOXID"),
                ora_rs.getString("BOXADDR").replace("'"," "),
                ora_rs.getString("LOCDESC") == null ? ora_rs.getString("LOCDESC") : ora_rs.getString("LOCDESC").replace("'",""),
                ora_rs.getString("LOCCITY").replace("'", " "),
                ora_rs.getString("LASTMF"),
                ora_rs.getString("LASTSAT").equals("11:58pm") ? "null": ora_rs.getString("LASTSAT"),
                ora_rs.getString("BOXTYPE"),
                ora_rs.getString("SVCCLAS"),
                ora_rs.getString("DROPZIP5"),
                ora_rs.getString("DROPPER_ID")});

            System.out.println(ora_rs.getRow());
        }

        System.out.println("Finished assigning ResultSet to List.");

        //leading statement for the following loop
        String query = "insert into random_selection "
                  + "(RANDNUM,QUARTER,OZIP3,BOXID,BOXADDR,LOCDESC,LOCCITY,LASTMF,LASTSAT,BOXTYPE,SVCCLAS,DROPZIP5,DROPPER_ID) VALUES";

        int jj = 0;

        //loop through random_selection_array creating an INSERT statement to insert 999 entries at a time
        //this is done to speed up the process
        for(int ii = 0;ii<random_selection.size();ii++){

            String[] array_holder = random_selection.get(ii);

            query = query
                  + "("
                  + "'"+array_holder[0]+"',"
                  + "'"+array_holder[1]+"',"
                  + "'"+array_holder[2]+"',"
                  + "'"+array_holder[3]+"',"
                  + "'"+array_holder[4]+"',"
                  + "'"+array_holder[5]+"',"
                  + "'"+array_holder[6]+"',"
                  + "'"+array_holder[7]+"',"
                  + "'"+array_holder[8]+"',"
                  + "'"+array_holder[9]+"',"
                  + "'"+array_holder[10]+"',"
                  + "'"+array_holder[11]+"',"
                  + "'"+new sun.misc.BASE64Encoder().encode(encrypt(array_holder[12]))+"'),";

            //every 999 iterations enter here
            if (jj > 998){
                //add |%| to the end of the string so that you can remove the final ','
                query = query+"|%|"; 
                query = query.replace(",|%|","");

                System.out.println(query);

                //sql_stmt.executeUpdate(query);
                query = "insert into random_selection (RANDNUM,QUARTER,OZIP3,BOXID,BOXADDR,LOCDESC,LOCCITY,LASTMF,LASTSAT,BOXTYPE,SVCCLAS,DROPZIP5,DROPPER_ID) VALUES";
                jj = 0;
            }
            jj++;

            //the last few entries will be added one at a time to prevent nulls records from being inserted
            if (ii > (random_selection.size() / 999) * 999){
                //add |%| to the end of the string so that you can remove the final ','
                query = query+"|%|";
                query = query.replace(",|%|","");

                System.out.println(query);

                //sql_stmt.executeUpdate(query);
                query = "insert into random_selection (RANDNUM,QUARTER,OZIP3,BOXID,BOXADDR,LOCDESC,LOCCITY,LASTMF,LASTSAT,BOXTYPE,SVCCLAS,DROPZIP5,DROPPER_ID) VALUES";
            }
        }
    }
}

The client wants to refrain from any open connections between the 2 servers. 客户端希望避免2个服务器之间的任何打开的连接。

The problem with this is likely with the large number of inserts being done on the MS SQL server. 与此相关的问题可能是由于在MS SQL服务器上完成了大量插入操作。 It's not very efficient to do that. 这样做不是很有效。

The correct way to transfer data between two databases (without linking) is to bcp rows in and out. 在两个数据库之间传输数据(不链接)的正确方法是将bcp行输入和输出。

First, keep in mind that I don't have any experience with BCP outside of sybase. 首先,请记住,我在sybase之外没有使用BCP的经验。

  1. Figure out how to get your data into MS bcp format. 弄清楚如何将数据转换为MS bcp格式。 There are a few ways this could be done. 有几种方法可以做到这一点。 I would try to create a view with all required in the oracle db and bcp out from there, but that may not be possible with the encrypt() stuff. 我会尝试在oracle db和bcp中创建所有必需的视图,但是使用crypto()可能无法实现。

  2. bcp in. bcp输入。

First of all, instead of guessing, you should actually write out to the console how long it ACTUALLY takes for each of those areas that you think are slow. 首先,不要猜测,您实际上应该向控制台写出您认为很慢的每个区域实际需要多长时间。 :) Second, you should use a prepared statement and use addBatch and executeBatch. :)其次,您应该使用准备好的语句,并使用addBatch和executeBatch。 In C# I would use SqlBulkCopy, but I don't think Java has a class like that, so you should try addBatch and executeBatch. 在C#中,我将使用SqlBulkCopy,但我不认为Java具有这样的类,因此您应该尝试addBatch和executeBatch。 If that is still too slow, then I would use BULK INSERT: http://msdn.microsoft.com/en-us/library/ms188365.aspx 如果那仍然太慢,那么我将使用批量插入: http : //msdn.microsoft.com/zh-cn/library/ms188365.aspx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM