建立專案情境 10
這是我針對某一個[Module]內的[Work Items]的效能做的效能調校 :
1. [module 1] : 共 6 項作業
(1). 作業1(Work Item 1) : OK,但會Call 外部系統的接口( [External Module Name 1].[Method 1]),可能有時會慢。我測的時候還好。
(2). 作業2 : OK,SQL Plain Cost 很低,Cost 只有 : 12
(3). 作業3 : 較慢 ,因為 資料筆數較多,Total : 6,367,125,有走 INDEX (UNIQUE SCAN),建議 做 table : online table reorganization
-- [Table 1]
select a.field_name2
from [Table 1] a
where a.field_name1 = '2173587'
;
-- (1). PK_ [Table 1] field_name1
-- (2). UNI_CON_ [Table 1]__field_name1 field_name1
(4). 作業4 : 較慢,因為 SQL Plain Cost 較高,SQL Plain Cost : 1712,且查詢的 Condition 條件沒有落在 PK, 或 INDEX,所以走 TABLE ACCESS (FULL ACCESS) SCAN
(5). 作業5 : OK
(6). 作業6 : OK
1. [module 2] :
(1). 作業2 : ....
(2). 作業3 : 因要判斷任一[category][判斷1],所以不改邏輯。
a. Java 單純針對[已經從DB取值出來的Category] for loop 速度夠快,且for loop內沒有[其他的DB Process]
以下為測試Java Code內單純的for loop(for loop : 1000000 筆)的執行時間測試(測試情境如以下的 a):
class ForLoopTest1 {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
long total = 0;
for (int i = 0; i < 1000000; i++) {
total += i;
}
System.out.println("Passing checkpoint " + total);
long stopTime = System.currentTimeMillis();
long elapsedTime = stopTime - startTime;
System.out.println(elapsedTime);
}
b. Java 針對[已經從DB取值出來的Category] for loop 速度夠快,但for loop有[其他的DB Process]:
[其他的DB Process] 包含以下 :
(a). db.getConnection()
(b). StringBuffer sb.append
(c). con.prepareStatement(sb.toString())
(d). ps.setting...
(e). ps.executeQuery()
(f). while (rs.next()) {}
(g). db.close()
public String [theMethod1](Integer [param1], String [param2]) {
String [param2]Result = null;
[DB Util 1] db = new [DB Util 1]();
[DB Util 1] db2 = new [DB Util 1]();
PreparedStatement ps = null;
PreparedStatement ps2 = null;
ResultSet rs = null;
ResultSet rs2 = null;
//Test By : [Tester 1]
System.out.println("[DAO1][theMethod1] -- Test By : [Tester 1]");
//Test Case 1 : a
long startTime3 = System.currentTimeMillis();
long total3 = 0;
for (int i = 0; i < 10000000; i++) {
total3 += i;
}
System.out.println(">>> Passing checkpoint : " + total3);
//Test Case 2 : b
long total = 0;
long startTime = System.currentTimeMillis();
try {
total ++;
db.connect();
Connection con = db.getConnection();
StringBuffer sb = new StringBuffer("");
sb.append(" select * from [table1] where [field1] = ? ");
sb.append(" and [param2]_id = ?");
ps = con.prepareStatement(sb.toString());
ps.setInt(1, [param1]);
ps.setString(2, [param2]);
rs = ps.executeQuery();
while (rs.next()) {
[param2]Result = rs.getString("[param2]_ID");
}
} catch (Exception e) {
throw ExceptionFactory.parse(e);
} finally {
[DB Util 1].closeAll(rs, ps, db);
}
System.out.println(">>> Passing checkpoint : " + total);
long stopTime = System.currentTimeMillis();
long elapsedTime = stopTime - startTime;
System.out.println(">>> elapsedTime : " + elapsedTime);
//Test By : [Tester 1]
long total2 = 0;
long startTime2 = System.currentTimeMillis();
try {
total2 ++;
db2.connect();
Connection con2 = db2.getConnection();
StringBuffer sb2 = new StringBuffer("");
sb2.append(" select [param2]_id from [table1] where [field1] = ? ");
sb2.append(" and [param2]_id = ?");
ps2 = con2.prepareStatement(sb2.toString());
ps2.setInt(1, [param1]);
ps2.setString(2, [param2]);
rs2 = ps2.executeQuery();
while (rs2.next()) {
[param2]Result = rs2.getString("[param2]_ID");
}
} catch (Exception e) {
throw ExceptionFactory.parse(e);
} finally {
[DB Util 1].closeAll(rs2, ps2, db2);
}
System.out.println(">>> Passing checkpoint : " + total2);
long stopTime2 = System.currentTimeMillis();
long elapsedTime2 = stopTime2 - startTime2;
System.out.println(">>> elapsedTime2 : " + elapsedTime2);
return [param2]Result;
}
[測試的結果] 如下 : [theMethod1]在此系統內:經[Module 1]的某個[主要的Action]執行後,節錄[theMethod1]被執行的部分結果: [DAO1][theMethod1] -- Test By : [Tester 1] >>> Passing checkpoint : 49999995000000 -- Java 單純針對[沒有從DB取值出來Category] for loop >>> elapsedTime3 : 4 >>> Passing checkpoint : 1 -- [其他的DB Process 1] >>> elapsedTime : 5 >>> Passing checkpoint : 1 -- [其他的DB Process 2] >>> elapsedTime2 : 5 [DAO1][theMethod1] -- Test By : [Tester 1] -- Java 單純針對[沒有從DB取值出來Category] for loop >>> Passing checkpoint : 10000000 >>> elapsedTime3 : 5 >>> Passing checkpoint : 1 -- [其他的DB Process 1] >>> elapsedTime : 9 >>> Passing checkpoint : 1 -- [其他的DB Process 2] >>> elapsedTime2 : 4 [DAO1][theMethod1] -- Test By : [Tester 1] -- Java 單純針對[沒有從DB取值出來Category] for loop >>> Passing checkpoint : 10000000 >>> elapsedTime3 : 4 >>> Passing checkpoint : 1 -- [其他的DB Process 1] >>> elapsedTime : 27 >>> Passing checkpoint : 1 -- [其他的DB Process 2] >>> elapsedTime2 : 8 [DAO1][theMethod1] -- Test By : [Tester 1] -- Java 單純針對[沒有從DB取值出來Category] for loop >>> Passing checkpoint : 10000000 >>> elapsedTime3 : 4 >>> Passing checkpoint : 1 -- [其他的DB Process 1] >>> elapsedTime : 12 >>> Passing checkpoint : 1 -- [其他的DB Process 2] >>> elapsedTime2 : 5 [DAO1][theMethod1] -- Test By : [Tester 1] -- Java 單純針對[沒有從DB取值出來Category] for loop >>> Passing checkpoint : 10000000 >>> elapsedTime3 : 4 >>> Passing checkpoint : 1 -- [其他的DB Process 1] >>> elapsedTime : 5 >>> Passing checkpoint : 1 -- [其他的DB Process 2] >>> elapsedTime2 : 5 Java 單純針對[沒有從DB取值出來Category] for loop,在此[theMethod1]內,共for loop : 49999995000000 次(49兆次),每次執行的總時間為:4 ~ 5 毫秒(elapsedTime3), [其他的DB Process 1],在此[theMethod1]內,共for loop : 1 次,每次執行的總時間為:5 ~ 27 毫秒(elapsedTime), [其他的DB Process 2],在此[theMethod1]內,共for loop : 1 次,每次執行的總時間為:4 ~ 8 毫秒(elapsedTime),
此[theMethod1],於此[系統內],由[All Modules]的所有[All Actions]執行後,總計被執行:138次。(ref : 20180509-1-ALL-次數.txt)。
此實驗足以顯示: (a). Java 單純針對[沒有從DB取值出來Category] for loop,在此SUN Java的Method內,總共要for loop高達 : 10000000 次(100萬次), 所需的時間,才與SUN Java JDBC的SQL查詢作業時間相當。 (b). SQL output 只有用到 : 某一個[field],那麼,建議不用 *:即,將 select * from ~,改成 select [the_field] from ~ 。 所以,針對[module 2]/作業3,效能調校的評估結果依據是正確的 : 因要判斷任一[category][判斷1],所以不改邏輯(測試情境如以下的 a)。
這是我針對某一個[Module]內的[Work Items]的效能做的效能調校 :
1. [module 1] : 共 6 項作業
(1). 作業1(Work Item 1) : OK,但會Call 外部系統的接口( [External Module Name 1].[Method 1]),可能有時會慢。我測的時候還好。
(2). 作業2 : OK,SQL Plain Cost 很低,Cost 只有 : 12
(3). 作業3 : 較慢 ,因為 資料筆數較多,Total : 6,367,125,有走 INDEX (UNIQUE SCAN),建議 做 table : online table reorganization
-- [Table 1]
select a.field_name2
from [Table 1] a
where a.field_name1 = '2173587'
;
-- (1). PK_ [Table 1] field_name1
-- (2). UNI_CON_ [Table 1]__field_name1 field_name1
(4). 作業4 : 較慢,因為 SQL Plain Cost 較高,SQL Plain Cost : 1712,且查詢的 Condition 條件沒有落在 PK, 或 INDEX,所以走 TABLE ACCESS (FULL ACCESS) SCAN
(5). 作業5 : OK
(6). 作業6 : OK
1. [module 2] :
(1). 作業2 : ....
(2). 作業3 : 因要判斷任一[category][判斷1],所以不改邏輯。
a. Java 單純針對[已經從DB取值出來的Category] for loop 速度夠快,且for loop內沒有[其他的DB Process]
以下為測試Java Code內單純的for loop(for loop : 1000000 筆)的執行時間測試(測試情境如以下的 a):
class ForLoopTest1 {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
long total = 0;
for (int i = 0; i < 1000000; i++) {
total += i;
}
System.out.println("Passing checkpoint " + total);
long stopTime = System.currentTimeMillis();
long elapsedTime = stopTime - startTime;
System.out.println(elapsedTime);
}
b. Java 針對[已經從DB取值出來的Category] for loop 速度夠快,但for loop有[其他的DB Process]:
[其他的DB Process] 包含以下 :
(a). db.getConnection()
(b). StringBuffer sb.append
(c). con.prepareStatement(sb.toString())
(d). ps.setting...
(e). ps.executeQuery()
(f). while (rs.next()) {}
(g). db.close()
public String [theMethod1](Integer [param1], String [param2]) {
String [param2]Result = null;
[DB Util 1] db = new [DB Util 1]();
[DB Util 1] db2 = new [DB Util 1]();
PreparedStatement ps = null;
PreparedStatement ps2 = null;
ResultSet rs = null;
ResultSet rs2 = null;
//Test By : [Tester 1]
System.out.println("[DAO1][theMethod1] -- Test By : [Tester 1]");
//Test Case 1 : a
long startTime3 = System.currentTimeMillis();
long total3 = 0;
for (int i = 0; i < 10000000; i++) {
total3 += i;
}
System.out.println(">>> Passing checkpoint : " + total3);
//Test Case 2 : b
long total = 0;
long startTime = System.currentTimeMillis();
try {
total ++;
db.connect();
Connection con = db.getConnection();
StringBuffer sb = new StringBuffer("");
sb.append(" select * from [table1] where [field1] = ? ");
sb.append(" and [param2]_id = ?");
ps = con.prepareStatement(sb.toString());
ps.setInt(1, [param1]);
ps.setString(2, [param2]);
rs = ps.executeQuery();
while (rs.next()) {
[param2]Result = rs.getString("[param2]_ID");
}
} catch (Exception e) {
throw ExceptionFactory.parse(e);
} finally {
[DB Util 1].closeAll(rs, ps, db);
}
System.out.println(">>> Passing checkpoint : " + total);
long stopTime = System.currentTimeMillis();
long elapsedTime = stopTime - startTime;
System.out.println(">>> elapsedTime : " + elapsedTime);
//Test By : [Tester 1]
long total2 = 0;
long startTime2 = System.currentTimeMillis();
try {
total2 ++;
db2.connect();
Connection con2 = db2.getConnection();
StringBuffer sb2 = new StringBuffer("");
sb2.append(" select [param2]_id from [table1] where [field1] = ? ");
sb2.append(" and [param2]_id = ?");
ps2 = con2.prepareStatement(sb2.toString());
ps2.setInt(1, [param1]);
ps2.setString(2, [param2]);
rs2 = ps2.executeQuery();
while (rs2.next()) {
[param2]Result = rs2.getString("[param2]_ID");
}
} catch (Exception e) {
throw ExceptionFactory.parse(e);
} finally {
[DB Util 1].closeAll(rs2, ps2, db2);
}
System.out.println(">>> Passing checkpoint : " + total2);
long stopTime2 = System.currentTimeMillis();
long elapsedTime2 = stopTime2 - startTime2;
System.out.println(">>> elapsedTime2 : " + elapsedTime2);
return [param2]Result;
}
[測試的結果] 如下 : [theMethod1]在此系統內:經[Module 1]的某個[主要的Action]執行後,節錄[theMethod1]被執行的部分結果: [DAO1][theMethod1] -- Test By : [Tester 1] >>> Passing checkpoint : 49999995000000 -- Java 單純針對[沒有從DB取值出來Category] for loop >>> elapsedTime3 : 4 >>> Passing checkpoint : 1 -- [其他的DB Process 1] >>> elapsedTime : 5 >>> Passing checkpoint : 1 -- [其他的DB Process 2] >>> elapsedTime2 : 5 [DAO1][theMethod1] -- Test By : [Tester 1] -- Java 單純針對[沒有從DB取值出來Category] for loop >>> Passing checkpoint : 10000000 >>> elapsedTime3 : 5 >>> Passing checkpoint : 1 -- [其他的DB Process 1] >>> elapsedTime : 9 >>> Passing checkpoint : 1 -- [其他的DB Process 2] >>> elapsedTime2 : 4 [DAO1][theMethod1] -- Test By : [Tester 1] -- Java 單純針對[沒有從DB取值出來Category] for loop >>> Passing checkpoint : 10000000 >>> elapsedTime3 : 4 >>> Passing checkpoint : 1 -- [其他的DB Process 1] >>> elapsedTime : 27 >>> Passing checkpoint : 1 -- [其他的DB Process 2] >>> elapsedTime2 : 8 [DAO1][theMethod1] -- Test By : [Tester 1] -- Java 單純針對[沒有從DB取值出來Category] for loop >>> Passing checkpoint : 10000000 >>> elapsedTime3 : 4 >>> Passing checkpoint : 1 -- [其他的DB Process 1] >>> elapsedTime : 12 >>> Passing checkpoint : 1 -- [其他的DB Process 2] >>> elapsedTime2 : 5 [DAO1][theMethod1] -- Test By : [Tester 1] -- Java 單純針對[沒有從DB取值出來Category] for loop >>> Passing checkpoint : 10000000 >>> elapsedTime3 : 4 >>> Passing checkpoint : 1 -- [其他的DB Process 1] >>> elapsedTime : 5 >>> Passing checkpoint : 1 -- [其他的DB Process 2] >>> elapsedTime2 : 5 Java 單純針對[沒有從DB取值出來Category] for loop,在此[theMethod1]內,共for loop : 49999995000000 次(49兆次),每次執行的總時間為:4 ~ 5 毫秒(elapsedTime3), [其他的DB Process 1],在此[theMethod1]內,共for loop : 1 次,每次執行的總時間為:5 ~ 27 毫秒(elapsedTime), [其他的DB Process 2],在此[theMethod1]內,共for loop : 1 次,每次執行的總時間為:4 ~ 8 毫秒(elapsedTime),
此[theMethod1],於此[系統內],由[All Modules]的所有[All Actions]執行後,總計被執行:138次。(ref : 20180509-1-ALL-次數.txt)。
此實驗足以顯示: (a). Java 單純針對[沒有從DB取值出來Category] for loop,在此SUN Java的Method內,總共要for loop高達 : 10000000 次(100萬次), 所需的時間,才與SUN Java JDBC的SQL查詢作業時間相當。 (b). SQL output 只有用到 : 某一個[field],那麼,建議不用 *:即,將 select * from ~,改成 select [the_field] from ~ 。 所以,針對[module 2]/作業3,效能調校的評估結果依據是正確的 : 因要判斷任一[category][判斷1],所以不改邏輯(測試情境如以下的 a)。