Site Search :
Standard Enterprise XML Methodology Pattern Setting Tunning Other
Article Contributors
GuestBook
Javapattern Maven
XSourceGen Dev
JetSpeed Test
JLook Image
jLook Family Site


Java JDBC Performance Tip(2)-Insert, Delete Speed up!
 
Áö³­¹ø ¾ÆƼŬ¿¡¼­´Â select¸¦ ºÃ´Ù. À̹øÆí¿¡¼­´Â Insert, Delete Batch¸¦ º¼°ÍÀ̸ç, ¾î¶»°Ô ±¸»çÇÏ´ÂÁöÀÇ ¿¹Á¦¸¦ »ìÆ캸µµ·Ï ÇÑ´Ù. ( 2003/04/15 ) 1268
Written by ienvyou - ÃÖÁö¿õ
1 of 1
 

ÀÌÀü ¾ÆƼŬ¿¡¼­´Â database select speedup¿¡ ´ëÇÏ¿© ¾Ë¾Æº¸¾Ò´Ù. À̹ø Æí¿¡¼­´Â update¸¦ Á¦¿ÜÇÑ
insert, delete tranactionÀÇ ¼Óµµ¸¦ ÃÖ´ë·Î ²ø¾î¿Ã¸± ¼ö ÀÖ´Â ¹æ¾ÈÀ» »ìÆ캸ÀÚ.

¢º Insert, Delete Query speed up!

JDBC 2.0¿¡¼­´Â ±âº»ÀûÀ¸·Î scrollableÇÑ ¸Þ¼ÒµåµîÀÇ À¯¿¬¼ºÀÖ´Â ¸Þ¼Òµåµé°ú  batch processing¿¡ °ü·ÃµÈ 
¸Þ¼Òµå°¡ Ãß°¡µÇ¾ú´Ù. 

±×°Ô ¹Ù·Î ¾î¶² °ÍÀ̳ÄÇϸé Statement, PreparedStatement ÀÎÅÍÆäÀ̽ºÀÇ addBatch(String sql),
addBatch()¸Þ¼ÒµåÀÌ´Ù. Pro*C°°Àº °æ¿ì ±âº»ÀûÀ¸·Î array processingÀ» ÀÌ¿ëÇÏ¿© µ¥ÀÌÅͺ£À̽º¿¡
ÀÛ¾÷À» ÇϹǷΠ»ó´çÇÑ ÆÛÆ÷¸Õ½º¸¦ ³¾ ¼ö Àִµ¥ À̸¦ ÀÚ¹ÙÃøÀ¸·Î º¯È¯ÇÑ°ÍÀÌ ¹Ù·Î addBatch¸Þ¼ÒµåÀÎ
°ÍÀÌ´Ù.

÷º¸¾Ò´Â°¡? ¾Æ´Ï¸é ¾Æ·¡ÀÇ BMT¾ÆƼŬ¿¡¼­µµ º¸¾Ò´Â°¡? 
Other--> Development¸¦ º¸°Ô µÇ¸é Java vs Pro*CÀÇ ºñ±³ÀÚ·á°¡ ÀÖ´Ù. ÇѹøÀо±â ¹Ù¶ó¸ç ±× ³»¿ëÀÇ
»ó¼¼ºÎºÐÀ» °£·«ÇÑ ÄÚµùÀ¸·Î¼­ ´ç½Å¿¡°Ô º¸¿©ÁÖ°íÀÚ ÇÑ´Ù.

±âº»ÀûÀ¸·Î java¿¡¼­µµ ±×·¯ÇÑ ¹èÄ¡±â´ÉÀ» »ç¿ëÇÏ°íÀÚ ÇÑ´Ù°í ÇÏ°í, ´ç½ÅÀÌ ¸¸¾à µå¶óÀ̹ö °³¹ßÀÚ¶ó°í Çϸé
¾î¶»°Ô µ¥ÀÌÅͺ£À̽º¿¡ ÀÛ¾÷À» ÇÒ°ÍÀΰ¡? 

±×³ª¸¶ setAutoCommit(false)¸¦ connection¿¡ ¶§·Á³Ö¾î³õÀ¸¸é commit¿¡ ´ëÇÑ ±×¸¸Å­ÀÇ ºñ¿ëÀÌ ¶³¾îÁú°ÍÀ̶ó´Â
°É ¾Ë°í ÀÖ´Ù¸é ´ÙÇàÀÌ°Ú´Ù. ÀÚ. ±×·¯¸é µ¥ÀÌÅ͸¦ ¼ÒÀ§ "¹Ð¾î³Ö´Â´Ù"¶ó°í À̾߱âÇßÀ» ¶§ °¡Àå ÃÖ¼±Ã¥Àº?
°Ç´ç ÇÏ´Â °Ç ¹«¸®ÀÏÅ×°í, À½~ Àڹٴϱî CollectionÀ» ÀÌ¿ëÇغ¸¸é µüÀÌ°Ú´Ù. 

±×¸®°í CollectionÀ» ÀÌ¿ëÇÑ´Ù¸é µé¾î¿À´Â µ¥ÀÌÅÍ´Â Áߺ¹À» Çã¿ëÇÏ°í ¼ø¼­µµ ÀÖ¾î¾ß ÇÒÅ״ϱî
List °è¿­À» »ç¿ëÇÏ´Â °ÍÀ» ÁÁ°Ú°í.. ³î»õÀÇ °á·ÐÀº ListÁß¿¡¼­µµ Á¦ÀÏ ÆÛÆ÷¸Õ½º°¡ ÁÁÀº ArrayList¸¦
»ç¿ëÇÏ´Â°Ô µüÀÏ°ÍÀ̶ó°í »ý°¢Çß´Ù. ÇÏÁö¸¸ ½ÇÁ¦ Driver´Â ¾î¶°ÇÑ ÀÚ¹Ù¹öÁ¯¿¡¼­µµ ¸Â¾Æ¾ß Çϱ⠶§¹®¿¡
1.2ºÎÅÍ »ç¿ëµÇ´Â ArrayList´Â Á» °í·ÁÇغ¼¸¸µµ ÇÏ´Ù. 

±×·¯¸é ¹¹°¡ µé¾î¿À´Â sql¹®Àå¿¡ ´ëÇÑ ÀúÀå¼Ò·Î Àû´çÇÒ °ÍÀΰ¡? ´äÀº Vector!! ¿Ö VectorÀÎÁö´Â ¼³¸íÇÏÁö
¾Ê°Ú´Ù. ÀÌÁ¤µµ ±ÛÀд ´ç½ÅÁ¤µµ¶ó¸é API´Â ¾î´ÀÁ¤µµ ¼÷ÁöÇÏ°í ÀÖÀ» °Å¶ó´Â ³î»õÀÇ »ý°¢¶§¹®ÀÌ´Ù.

¿ì¼± ±×·¯¸é ½ÇÁ¦ OracleÀ» ¿¹·Î driver³»ºÎ³ª Çѹø º¸µµ·Ï ÇÒ±î?

JDBC API Statement ÀÎÅÍÆäÀ̽ºÀÇ ±¸ÇöüÀÎ OracleStatementÄÚµåÀÇ addBatch¸Þ¼Òµå¸¦ Àá±ñº¸ÀÚ


    public synchronized void addBatch(String s)
        throws SQLException
    {
        addBatchItem(s);
    }

    private void addBatchItem(String s)
    {
        m_batchItems.addElement(s);
    }
¾î¶ó? addElement¸¦ »ç¿ëÇÏ´Â °É º¸´Ï ³î»õ°¡ »ý°¢Çß´ø °Íó·³ Vector¸¦ »ç¿ëÇÏ°í ÀÖ´Ù. Áï batch¸¦ À§ÇÑ ÀúÀå¼Ò·Î¼­ Vector class¸¦ »ç¿ëÁßÀÎ °ÍÀÌ´Ù. ±×·¯¸é StatementŬ·¡½ºÀÇ ½ÇÁ¦ batch execute ¸í·É¾îÀÎ executeBatch()¸Þ¼Òµå¸¦ º¸µµ·Ï ÇÏÀÚ.

    public int[] executeBatch()
        throws SQLException
    {
        synchronized(connection)
        {
            synchronized(this)
            {
                int i = 0;
                int j = getBatchSize();
                if(j <= 0)
                {
                    int ai[] = new int[0];
                    return ai;
                }
                int ai2[] = new int[j];
                Object obj = null;
                Object obj1 = null;
                Object obj2 = null;
                boolean flag = false;
                ensureOpen();
                prepare_for_new_result(true);
                try
                {
                    connection.needLine();
                    for(i = 0; i < j; i++)
                    {
                        String s = getBatchItem(i);
                        String s1 = expandSqlEscapes(s);
                        byte abyte0[] = strToDbaccessBytes(s1);
                        byte byte0 = getSqlKind(s1);
                        if(byte0 == 0)
                            DBError.throwBatchUpdateException(80, "invalid SELECT batch command " + i, i, ai2);
                        ai2[i] = parseExecuteFetchWithTimeout(dbstmt, byte0, abyte0, null, 1, null, 1);
                        if(ai2[i] < 0)
                            DBError.throwBatchUpdateException(81, "command return value " + ai2[i], i, ai2);
                    }

                }
                catch(IOException ioexception)
                {
                    DBError.throwBatchUpdateException(81, ioexception.getMessage(), i, ai2);
                }
                catch(SQLException sqlexception)
                {
                    if(sqlexception instanceof BatchUpdateException)
                        throw sqlexception;
                    DBError.throwBatchUpdateException(81, sqlexception.getMessage(), i, ai2);
                }
                finally
                {
                    clearBatchItems();
                }
                int ai1[] = ai2;
                return ai1;
            }
        }
    }

À§¿¡¼­ º¸¸é ´ç¿¬È÷ connectionÀº µ¿±âÈ­µÇ¾îÁ®¾ß ÇϹǷΠsynch°É¾î³õ°í ÀÛ¾÷ÇÒ°Ô »·Çϸç, parseExecuteFetchWithTimeout¸Þ¼Òµå°¡ ½ÇÁ¦ updateÀÛ¾÷À» ÀÌ·ç°Ô²û Çϴµ¥ Àú³ðÀº timeoutÀÌ °É·ÁÀÖÀ¸¸é ŸÀÌ¸Ó ÀÛµ¿½ÃÅ°°í statement¿¡ update¶§¸®´Â ÀÛ¾÷À» Çϸç, timeoutÀÌ 0ÀÌ¸é ¹Ù·Î updateÀÌ´Ù. º¹ÀâÇÑ°¡? PreparedStatement(ÀÌÇÏ PS)ÀÇ addBatch()¸Þ¼Òµå´Â Á¶±Ý ´õ º¹ÀâÇϹǷΠ°£·«ÇÏ°Ô ¾î¶»°Ô ÀÛµ¿µÇ´ÂÁö¸¸ ¼³¸íÇÏ°Ú´Ù. PSÀÇ °æ¿ì´Â Äõ¸®°¡ ÀÌ¹Ì databaseÀÇ ³»ºÎ procedure·Î º¯È¯µÇ¾îÁ® Àֱ⠶§¹®¿¡ StreamÀ» ÀÌ¿ëÇÏ¿© µ¥ÀÌÅ͸¦ ¼¼ÆýÃÅ°´Â ÀÏÀ» ÇÑ´Ù´Â °ÍÀÌ Statement Batch¿Í Ʋ¸° Á¡ÀÌ´Ù. ±×·¸´Ù¸é Statement¿Í PreparedStatementÀÇ ¼ÓµµÂ÷ÀÌ´Â ¾ó¸¶³ª µÉ±î? ³î»õ´Â ÀÌ¹Ì ÀüºÎ ´Ù Çغñ⠶§¹®¿¡ ÀÌ°Ç ´ç½ÅÀÇ ¼÷Á¦·Î ³²°ÜµÎ°Ú´Ù. À§ÀÇ ³»¿ëº¹ÀâÇÏ¸é ¸ô¶óµµ µÊÀ» °­·ÂÈ÷ ÁÖÀåÇÑ´Ù. ´ç½ÅÀÌ JDBC Driver°³¹ßÀÚ°¡ ¾Æ´ÏÁö ¾ÊÀº°¡~!! ^^ ÀÚ ±×·³ ÀÌÁ¦ ÄÚ´õÀÇ ½ÅºÐÀ¸·Î µ¹¾Æ¿Ô´Ù°í °¡Á¤À» ÇÏ°í, API¸¦ ÀÌ¿ëÇÏ¿© ÄÚµùÀ̳ª Çѹø Çغ¸ÀÚ. ´Ü¼øÈ÷ API¸¦ »ç¿ëÇÏ´Â °ÍÀ̹ǷΠ°ÅâÇÏ°Ô ¼³¸íÇÏ°í Àڽðí ÇÒ ÇÊ¿äµµ ¾øÀÌ ¹Ù·Î µé¾î°£´Ù. ¾Ë¾Æ¼­ º¸¶ó~

public class BatchTest {
    private Connection getConnection(){
        // ¾Ë¾Æ¼­ ¿¬°áµé Ç϶ó~! ^^
    }
    
    private void close() {
        // ¾Ë¾Æ¼­ ¿¬°áÀ» ´Ý¾Æ¶ó
    }

    public void insertABT231Batch(){
        System.out.println(Utility.getTime() 
        + " Insert ABT231 Batch Start .. Transaction size is " + m_abt231InsertList.size());
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            StringBuffer query = new StringBuffer();
            query.append("INSERT INTO ABT231 ");
            query.append("(customer_no, item_cd, occur_amt, reason_cd, register_ymd, register_no) ");
            query.append(" VALUES (?, ?, ?, '9', ?, ?) ");

            conn = getConnection();
            conn.setAutoCommit(false);

            pstmt = conn.prepareStatement(query.toString());
            Iterator iter = m_abt231InsertList.iterator();
            int count = 0;

            while( iter.hasNext() ) {
                m_abt231 = (Abt231) iter.next();
                pstmt.setInt(1, m_abt231.getCustomerNo());
                pstmt.setString(2, m_abt231.getItemCd());
                pstmt.setLong(3, m_abt231.getOccurAmt());
                pstmt.setString(4, s_magamCurrentTime);
                pstmt.setInt(5, Integer.parseInt(s_workCd));
                pstmt.addBatch();
                count++;
                if( (count % 10000) == 0){
                    System.out.println(count + "°Ç ó¸®Áß");
                    pstmt.executeBatch();
                }
            }

            pstmt.executeBatch();
            conn.commit();
            System.out.println(Utility.getTime() + "] " + count + "°Ç ÀԷ¿Ϸá");
        } catch ( Exception e) {
            e.printStackTrace();
            try{
                conn.rollback();
            }catch(Exception e2) {e2.printStackTrace();}
        } finally {
            close(pstmt);
            close(conn);
        }
    }
}
À§¿¡¼­ À¯½ÉÈ÷ º¼°Å¶ó°í´Â boldü·Î ¾²¿©Áø ºÎºÐÀÇ ³»¿ë»ÓÀÌ´Ù. À§ÀÇ ³»¿ëÀº µ¥ÀÌÅͺ£À̽º¿¡¼­ ÃßÃâµÈ µ¥ÀÌÅ͸¦ ´Ù½Ã °è»êÇÏ¿© ´Ù¸¥ µ¥ÀÌÅͺ£À̽º Å×ÀÌºí¿¡ insertÇÏ´Â ³»¿ëÀ̸ç, ArrayList¿¡ ´ã±ä ´ë·®ÀÇ µ¥ÀÌÅ͸¦ iterationÇϸç batch¸¦ ½ÇÇàÇÏ´Â °ÍÀÌ´Ù. Á» ´õ ÀÚ¼¼ÇÑ ¸Þ¼Òµå ¼³¸íÀº APIÀÇ ³»¿ëÀ» ÂüÁ¶Çصµ ¹«¹æÇÒ µí ½Í´Ù. addBatch()óÀ½º¸´Â°¡? ±×·¯¸é ´Ù¸¥ Ŭ·¡½º¸¦ ¿¹·Î µé¾î¼­ java.langÆÐÅ°Áö Ŭ·¡½ºÀÇ ¸Þ¼Òµå´Â ÀÚÀ¯ÀÚÀç·Î ±¸»çÇÒ ÁÙ ¾Æ´Â°¡? ³î»õ°¡ ¾Æ´Â »ç¶÷µé³¢¸®ÀÇ °í¼ö¿¡ ´ëÇÑ Ç¥ÇöÀº ´ÙÀ½°ú °°´Ù. "Àú »ç¶÷Àº °É¾î´Ù´Ï´Â API¾ß~!" ¾Æ¹«·¸Áöµµ ¾ÊÀº °Í °°À¸¸é¼­µµ ¾ó¸¶³ª ÇÔÃàÀûÀΠǥÇöÀΰ¡~!! ( ³ª¸¸ ±×·±°¡? ¤¾¤¾) API¸¦ ÀÌ¿ëÇÏ¿© ½±°Ô ¸¸µé¼ö Àִµ¥µµ ¿¹Àü CÄÚµùó·³ ÇÔ¼ö ¿­³ª ¸¸µé¾î¼­ Àß ¸¸µé¾ú´Ù°í ÀÚ¶ûÇغÁÂ¥ À§ÀÇ °É¾î´Ù´Â APIÇÑÅ× ¸Á½Å´çÇÒ ¼ö ÀÖ´Ù´Â °É ¸í½ÉÇØ¾ß ÇÑ´Ù. Áß¿äÇÏ°Ô ¾²Àϼö ÀÖ´Â °ÍÀº ¹Ù·Î ¿·¿¡ ÀÖÀ¸¸ç, ´ç½Å´«¿¡ ¶çÁö ¾Ê´Â °ÍÀÌ ´ëºÎºÐÀÌ´Ù. µÎ ´« Å©°Ô ¶ß°í ´Ù³à¾ß ÇÑ´Ù. API°¡ ¹Ù·Î ±×°ÍÀÎ °ÍÀÌ´Ù.
¾ÆÂü. ±×¸®°í À§ÀÇ Äڵ尰Àº°Å Å×½ºÆ®ÇÒ¶§ À¢¸¸Çϸé TestCase¸¸µé¾î¼­ ÀÛ¼ºÇϽʼî. ½À°üÀÌ Áß¿äÇÕ´Ï´Ù. ´ÜÀ§Å×½ºÆ®ÀÇ Á߿伺Àº ³ªÁß¿¡ Ä®·³¾µÀÏ ÀÖÀ¸¸é ¾²µµ·Ï ÇÏ°Ú½À´Ï´Ù.
 
1
References
 
Java API
Copyright ¨Ï 2003 www.javapattern.info & www.jlook.com, an jLOOK co.,LTD