ä¸è¨ã®ããã«ä¸»ãã¼ã¨å¤ãããªããã¼ãã«ãããã¨ããã
ID | VALUE |
---|---|
1 | value1 |
2 | value2 |
3 | value3 |
ä¸è¨ã®ãã¼ãã«ããä¸è¨ã®ãããªCSVãã¡ã¤ã«ãå ¥åã¨ãã¦æ´æ°ãã¦ããããã°ã©ã ãèããã
1,update_value1 2,update_value2 3,update_value3
ç°å¢
æºå
æ´æ°å¯¾è±¡ã®ãã¼ãã«ãä½æãããã¼ã¿ãæ¿å ¥ãããè¨æ¸¬ã®åºæºãããããããã«ãããã¡ãã£ãã·ã¥ãã¯ãªã¢ãã¦ããããªããè¨æ¸¬å¯¾è±¡ã®ããã°ã©ã å®è¡åã«ä¸è¨ã®SQLãå®è¡ãã¦ããµã©ã®ç¶æ ãä½ããã¨ãã¨ããã
DROP TABLE UPDATE_TABLE PURGE; CREATE TABLE UPDATE_TABLE ( ID INTEGER NOT NULL , VALUE VARCHAR2(20) NOT NULL , CONSTRAINT UPDATE_TABLE_PK PRIMARY KEY ( ID ) ENABLE ); INSERT INTO UPDATE_TABLE(ID, VALUE) SELECT ROWNUM, dbms_random.string('X', 20) FROM (SELECT ROWNUM FROM all_catalog WHERE ROWNUM <= 1000), (SELECT ROWNUM FROM all_catalog WHERE ROWNUM <= 100); COMMIT; ALTER SYSTEM FLUSH BUFFER_CACHE;
æ´æ°å 容ãæ¸ãããCSVãã¡ã¤ã«ï¼input.csvï¼ã¯ãããªæããCSVãã¡ã¤ã«ã®åè¡ããã¼ãã«ã®ä¸è¡ã«ç¸å½ãã1åç®ã主ãã¼åã®IDã«ã2åç®ãå¤åã®VALUEã«ããããã対å¿ããã
1,AAA5X2444FCJ05D1RFZJ 2,AAAS3X74XE35JB0XZ5PS 3,AAAG7MX9T8UCVJ7724VI
è¨æ¸¬å¯¾è±¡ã®ããã°ã©ã
ä¸è¡ãã¤UPDATE
Javaã§CSVãã¡ã¤ã«ãèªã¿è¾¼ã¿ãä¸è¡ãã¤UPDATEãçºè¡ããã
public class UpdateFromFile { public static void main(String[] args) throws IOException, SQLException { final int IND_ID = 0; final int IND_VALUE = 1; final int PARAM_IND_ID= 2; final int PARAM_IND_VALUE = 1; long start = System.currentTimeMillis(); List<String> lines = Files.readAllLines(Paths.get("input.csv"), Charset.defaultCharset()); final String updateStr = "UPDATE update_table SET VALUE = ? WHERE ID = ?"; try (Connection connection = DriverManager.getConnection( "jdbc:oracle:thin:@192.168.0.20:1521:XE", "kagamihoge", "xxxx"); PreparedStatement sql = connection.prepareStatement(updateStr);) { connection.setAutoCommit(false); for (String idAndValue : lines) { String[] split = idAndValue.split(","); sql.setString(PARAM_IND_VALUE, split[IND_VALUE]); sql.setInt(PARAM_IND_ID, Integer.parseInt(split[IND_ID])); sql.executeUpdate(); } connection.commit(); } long end = System.currentTimeMillis(); System.out.println(end - start); } }
CASE使ç¨UPDATE
CASEå¼ã使ç¨ãã¦è¤æ°ã®UPDATEãã²ã¨ã¤ã«ã¾ã¨ãããåèï¼é人ã«å¦ã¶ SQLå¾¹åºæåæ¸ (CodeZine BOOKS) p.19 第ä¸é¨ éæ³ã®SQL 1-1 CASEå¼ã®ã¹ã¹ã¡ æ¡ä»¶ãåå²ãããUPDATE
Javaã«SQLãåãè¾¼ã¾ãã¦ãã¦åããã«ããããä¸è¨ã®ãããªSQLãCSVãã¡ã¤ã«50è¡ãã¨ã«1åçºè¡ãã¦ãããã³ã¼ãä¸ã§ã¯SQLã®æååå¤æ°ã«WHEN ã THENã50åç¹°ãè¿ãç¾ããã®ã§ã¡ãã£ã¨è¦ã¥ãããåå¼ãã¦ããã ãããã
UPDATE UPDATE_TABLE SET VALUE = CASE WHEN ID = 1 THEN 'update_value_1' WHEN ID = 2 THEN 'update_value_2' WHEN ID = 3 THEN 'update_value_3' ELSE VALUE END WHERE ID IN (1, 2, 3);
public class UpdateWithCaseFromFile { public static void main(String[] args) throws Exception { final int IND_ID = 0; final int IND_VALUE = 1; long start = System.currentTimeMillis(); List<String> lines = Files.readAllLines(Paths.get("input.csv"), Charset.defaultCharset()); final String updateStr = "UPDATE UPDATE_TABLE SET VALUE = CASE WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? WHEN ID = ? THEN ? ELSE VALUE END WHERE ID IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; try (Connection connection = DriverManager.getConnection( "jdbc:oracle:thin:@192.168.0.20:1521:XE", "kagamihoge", "xxxx"); PreparedStatement sql = connection.prepareStatement(updateStr);) { connection.setAutoCommit(false); int count = 0; for (String idAndValue : lines) { String[] split = idAndValue.split(","); count++; sql.setInt((count*2)-1, Integer.parseInt(split[IND_ID])); sql.setString(count*2, split[IND_VALUE]); sql.setInt(count + 100, Integer.parseInt(split[IND_ID])); if (count == 50) { sql.executeUpdate(); count = 0; } } connection.commit(); } long end = System.currentTimeMillis(); System.out.println(end - start); } }
ä¸æ表çµç±UPDATE
ä¸æ表ã«ãã¹ã¦ã®ãã¼ã¿ãINSERTãããã¨ããã®ä¸æ表ããã¿ã¼ã²ãããã¼ãã«ã¸ä¸åã®SQLã§UPDATEããã
ã¾ããä¸è¨ã®SQLã§ä¸æ表ãä½æããã
CREATE GLOBAL TEMPORARY TABLE TEMP_UPDATE_TABLE ( ID INTEGER NOT NULL , VALUE VARCHAR2(20) , CONSTRAINT TEMP_UPDATE_TABLE_PK PRIMARY KEY ( ID ) ENABLE ) ON COMMIT DELETE ROWS;
ä¸è¨ã®ä¸æ表ã«ãã¼ã¿ãINSERTãããã¨ãä¸è¨ã®SQLã§UPDATEããããã
MERGE INTO UPDATE_TABLE u USING ( SELECT ID temp_id, VALUE temp_value FROM temp_update_table ) t ON (u.ID = t.temp_id) WHEN MATCHED THEN UPDATE SET u.VALUE = t.temp_value;
public class UpdateThroughTemporaryFromFile { public static void main(String[] args) throws Exception { final int IND_ID = 0; final int IND_VALUE = 1; final int PARAM_IND_ID= 1; final int PARAM_IND_VALUE = 2; long start = System.currentTimeMillis(); List<String> lines = Files.readAllLines(Paths.get("input.csv"), Charset.defaultCharset()); final String insertIntoTempStr = "INSERT INTO temp_update_table(ID, VALUE) VALUES (?, ?)"; final String updateFromTempStr = "MERGE INTO UPDATE_TABLE u USING (SELECT ID temp_id, VALUE temp_value FROM temp_update_table) t ON (u.ID = t.temp_id) WHEN MATCHED THEN UPDATE SET u.VALUE = t.temp_value"; try (Connection connection = DriverManager.getConnection( "jdbc:oracle:thin:@192.168.0.20:1521:XE", "kagamihoge", "xxxx"); PreparedStatement sql = connection.prepareStatement(insertIntoTempStr); PreparedStatement updateSql = connection.prepareStatement(updateFromTempStr);) { connection.setAutoCommit(false); for (String idAndValue : lines) { String[] split = idAndValue.split(","); sql.setInt(PARAM_IND_ID, Integer.parseInt(split[IND_ID])); sql.setString(PARAM_IND_VALUE, split[IND_VALUE]); sql.executeUpdate(); } updateSql.executeUpdate(); connection.commit(); } long end = System.currentTimeMillis(); System.out.println(end - start); } }
å¤é¨è¡¨çµç±UPDATE
å¤é¨è¡¨ã§CSVãã¡ã¤ã«ãåç §ã§ããããã«ãããã¨ããã®å¤é¨è¡¨ããã¿ã¼ã²ãããã¼ãã«ã¸ä¸åã®UPDATEã§æ´æ°ããããã
ã¾ããCSVãã¡ã¤ã«ã«å¯¾å¿ããå¤é¨è¡¨ãä½æããããªãããã£ã¬ã¯ããªãªãã¸ã§ã¯ãã¨ãã¯ä½ææ¸ã¿ã¨ããã
DROP TABLE EXT_UPDATE_TABLE; CREATE TABLE EXT_UPDATE_TABLE ( ID INTEGER, VALUE VARCHAR(20) ) ORGANIZATION EXTERNAL ( TYPE ORACLE_LOADER DEFAULT DIRECTORY "EXTERNAL_DATA" ACCESS PARAMETERS ( RECORDS DELIMITED BY '\r\n' CHARACTERSET JA16SJISTILDE BADFILE "EXTERNAL_DATA":'BADFILE_LOG.bad' DISCARDFILE "EXTERNAL_LOGS":'DISCARDFILE_LOG.log' LOGFILE "EXTERNAL_LOGS":'LOGFILE_LOG.log' FIELDS TERMINATED BY ',' ( ID DECIMAL EXTERNAL, VALUE CHAR(20) ) ) LOCATION ('input.csv') );
å¤é¨è¡¨ã¨ã¿ã¼ã²ãããã¼ãã«ãJOINãã¦æ´æ°ããããã
MERGE INTO UPDATE_TABLE u USING ( SELECT ID e_id, VALUE e_value FROM EXT_UPDATE_TABLE ) e ON (u.ID = e.e_ID) WHEN MATCHED THEN UPDATE SET U.VALUE = E.E_VALUE; commit;
ãªããä¸è¨ã®ã¯ã¨ãªã¯ããæ¸ããæ°ãããã®ã ãORA-01779ã«ãªããããã¦11gã§ã¯BYPASS_UJVCãã³ãã使ããªãã®ã§ãä¸éçã«ã¯mergeã§ä»£ç¨ããã®ãä¸è¬çãããã
UPDATE ( SELECT u.ID u_id, u.VALUE u_value, e.VALUE e_value FROM UPDATE_TABLE u JOIN EXT_UPDATE_TABLE e ON u.ID = e.ID ) set u_value = e_value;
å®è¡çµæ
ææ³ | 1 | 2 | 3 |
---|---|---|---|
ä¸è¡ã㤠| 35906 | 35609 | 35360 |
CASEä½¿ç¨ | 4125 | 4032 | 3922 |
ä¸æ表çµç± | 44031 | 41468 | 41031 |
å¤é¨è¡¨çµç± | 2875 | 2109 | 2094 |
å¤é¨è¡¨ãå§åçã«æ©ãã次ã«CASE使ç¨ããã®ãã¨ããªãå·®ããããä¸è¡ãã¤ãä¸æ表çµç±ã¨ããçµæã«ãªã£ããæè¦çã«ã¯ãSQLã®çºè¡åæ°ãå°ãªããã°å°ãªãã»ã©æ©ããªãçãªã®ã§ãã»ã¼ãã®éãã®çµæã«ãªã£ã¦ããã®ã¯ç´å¾ãããã
ææ³ã¨ã
ãªãå®è¡æéã«å·®ãåºãã®ããstatspackã¬ãã¼ãã使ç¨ãã¦çç±ãèãã¦ã¿ããä¸è¨ã¯ãããããã®æ¹æ³ãå®è¡ããåå¾ã§ã®ã¬ãã¼ããããStatisticã»ã¯ã·ã§ã³ãã主ãªãã®ãæç²ãã¦ãããã®ã
Statistic | å¤é¨è¡¨ | CASEä½¿ç¨ | ä¸è¡ã㤠|
---|---|---|---|
SQL*Net roundtrips to/from client | 17 | 2,017 | 100,017 |
consistent gets | 1,959 | 19,804 | 200,635 |
consistent gets from cache | 1,959 | 19,804 | 200,635 |
db block changes | 202,948 | 15,903 | 202,789 |
db block gets | 104,425 | 6,539 | 104,246 |
db block gets from cache | 104,425 | 6,539 | 104,246 |
physical read total bytes | 11,183,104 | 11,632,640 | 12,198,912 |
physical write total bytes | 31,160,832 | 14,868,992 | 31,272,960 |
redo size | 29,857,800 | 14,303,736 | 29,808,544 |
undo change vector size | 11,158,016 | 6,749,292 | 11,139,192 |
Oracleã«ãããUPDATEã®åºæ¬çãªåãã ããæ´æ°ãããããã«ãã¼ã¿ãããã¯ãããããã¡ãã£ãã·ã¥ã«èªã¿è¾¼ã¿ãããããããããã¡ãã£ãã·ã¥ã«ããã°ããã¯çç¥ãããããã¡ãã£ãã·ã¥ã«å¤æ´ããå¤ãæ¸ãè¾¼ããUNDOã®åãã¯çç¥ãä¸è¡ãã¤UPDATEããå ´åã主ãã¼ã§æ´æ°å¯¾è±¡è¡ãä¸è¡ã«çµãè¾¼ããã®ã§ãã¾ãã¤ã³ããã¯ã¹çµç±ã§1ãããã¯ããã¼ã¿ãããã¯ã§1ãããã¯ã®è¨2åãããã¯ã¢ã¯ã»ã¹ãçºçãããã¬ãã¼ãã®è¡¨ãè¦ãã¨ãä¸è¡ãã¤ã®consistent getsã¯ç´20ä¸ã§ãï¼1 + 1ï¼Ã 10ä¸è¡ã§ç´20ä¸ã¨èããããã
次ã«case使ç¨ã®consistent getsã ããç´20ä¸ / 50ã§4000ãããã«ãªãããã ããªã£ã¦ããªããçç±ã¯ç¥èä¸è¶³ã§åãããªãããINLIST ITERATORã§ãã¼ã¿ãããã¯ã«ã¢ã¯ã»ã¹ããã¨ãã¯1ãããã¯1åãã¤èªã¿ã«è¡ãã ãããããã®è¾ºããªï¼ãã¨ããã®ãããã
ããã¦å¤é¨è¡¨çµç±ã¯å§åçã«consistent getsãå°ãªãããã®æ¤è¨¼ç¨ããã°ã©ã ã§ã¯çµå±å ¨è¡æ´æ°ãªã®ã§ãå ¨ãããã¯ã«ã¢ã¯ã»ã¹ãããã¨ã¯äººéã«ã¯åãã£ã¦ãããDBå´ããä¸çºã®UPDATEã§å ¨è¡æ´æ°ã ã¨å¤å¥ã§ããã¨ã1ã¤ã®ãã¼ã¿ãããã¯ã«å¯¾ããæ´æ°ã¯ã¾ã¨ãã¦è¡ã£ã¦è¯ãã¨å¤æã§ããã ããã¨æ¨æ¸¬ã§ããããã®çµæãconsistent getsã¯å°ãªããªããããããä¸è¡ãã¤æ´æ°ããå ´åã¯ã©ã足æ»ãã¦ããããã¯ã2åã¢ã¯ã»ã¹ããªããã°ãªããªãã®ã§ã両è ã®å·®ã¯å¤§ããéããã¨ã«ãªãããã®æ¤è¨¼ç¨ããã°ã©ã ã®å ´åããã¼ã¿ãããã¯ã®é ããé ã«æ´æ°ãã¦ãããããã£ãã·ã¥ãããçã¯é«ãã¨ã¯ãããUPDATEã¯ä»ã«ãããããªå¦çãããªããã°ãªããããã®ãªã¼ãã¼ããããç©ããç©ãã£ã¦å®è¡æéã®å·®ã«ãªã£ã¦ãããã¨èããããã
ã¾ããredo sizeã¨undo change vector sizeã®å·®ãç®ã«ä»ããcase使ç¨ã¯ä»ã«æ¯ã¹ã¦ç´ååã«ãªã£ã¦ããããããå®è¡æéãæå¶ãã主å ã«ãªã£ã¦ããã¨èãããããå¤é¨è¡¨çµç±ã®ä¸çºUPDATEããã£ã¨æ¸ã£ã¦ãããããªãã®ã§ããããä½æ CASE使ç¨ã ããããªã«ãæ¸ããã®çç±ã¯ã¡ãã£ã¨æãè³ããªããã¨ã¯ãããREDOãæ¸ãæè¦çãªçç±ã¯ãä¸åä¸åããããæ´æ°ããããããã©ã¼ãã¨ã¾ã¨ãã¦æ´æ°ããã»ãããããå¾è ã®æ¹ãå°ãããããã¨ãã£ãæ³åã¯ã¤ãã
ã¨ãããã¨ã¯ãCASE使ç¨ã§æ´æ°ããè¡ããã£ã¨å¢ããã¨éããªãããã ãINå¥ã«å¤§éã®å¤ãæå®ããã¨ä»ã®è¦å ã§é ããªããããªæ°ããã¦ãããå®éã«è©¦ãã¦ãªããã§ãªãã¨ããããªããããã¨ãJavaçµç±ã§ããã°ãããæ´æ°ãããã®ã§ãããä½µç¨ããã°å¤é¨è¡¨çµç±ã¨ã®é度差ã¯ããå°ãè©°ã¾ããããããªãããã ãä¸çºã®SQLã§æ¸ã¾ããããã·ã³ãã«ãã§ã¯ããã¿ã¯é©ããªãã®ã ãã©ãPreparedStatementã®ãã©ã¡ã¼ã¿ãä½ç¾åã¨ãä¸ã ã³ã¼ãã£ã³ã°ãããã©ãã