2014年4月29日 星期二

Java 資料庫存取效能評比

完成 Java 資料庫存取測試後, 今天要對 Access(MDB), Derby, 以及 MySQL 這三個資料庫作效能評比. 方式很簡單 但可能不專業, 就是建一個資料表, 填入 5000 筆資料, 然後刪除全部資料, 最後刪除資料表, 計算所費時間與記憶體. 計算時間差的方法參考 :

# Java 複習筆記 : 日期與時間 (續)

具體方式是先手動建立一個資料庫 test, 然後用下列程式新增一個資料表 users, 內有兩個欄位 : id 與 name, 然後用一個迴圈寫入 5000 筆資料, 再用一個迴圈刪除這 5000 筆資料, 最後刪除 users 資料表, 測試是在我的 ACER D260 小筆電上進行的, 所以效能數據比較差, 下面是測試 Access 資料庫的程式 :

import java.sql.*;
import java.util.*;
public class AccessLandmark {
  public static void main(String[] args) {
    long start=System.currentTimeMillis();
    long mem1=Runtime.getRuntime().freeMemory();
    JT.connectMDB("test.mdb");
    String col="id AUTOINCREMENT PRIMARY KEY,name VARCHAR(30)";
    System.out.println("建立資料表 users : " + JT.createTable("users",col));
    for (int i=0; i<5000; i++) {
      JT.runSQL("INSERT INTO users(name) VALUES('USER" + i + "')");
      }
    System.out.println("插入資料 : OK");
    for (int i=0; i<5000; i++) {
      JT.runSQL("DELETE * FROM users");
      }
    System.out.println("刪除資料 : OK");
    System.out.println("刪除資料表 users : " + JT.dropTable("users"));
    JT.closeDB();
    long end=System.currentTimeMillis();
    long mem2=Runtime.getRuntime().freeMemory();
    System.out.println("耗費時間 : " + (end-start) + " ms");
    System.out.println("耗費記憶體 : " + (mem1-mem2) + " bytes");
    }
  }

執行三次結果 :

E:\Java\JT>java AccessLandmark
建立資料表 users : true
插入資料 : OK
刪除資料 : OK
刪除資料表 users : true
耗費時間 : 17078 ms
耗費記憶體 : 1461024 bytes

E:\Java\JT>java AccessLandmark
建立資料表 users : true
插入資料 : OK
刪除資料 : OK
刪除資料表 users : true
耗費時間 : 16625 ms
耗費記憶體 : 1461056 bytes

E:\Java\JT>java AccessLandmark
建立資料表 users : true
插入資料 : OK
刪除資料 : OK
刪除資料表 users : true
耗費時間 : 16906 ms
耗費記憶體 : 1460928 bytes

ACCESS 平均耗時 17 秒, 使用了 1.5MB 記憶體. 數據穩定, 變化不大.

下面是 Derby 資料庫的測試程式 :

import java.sql.*;
import java.util.*;
public class DerbyLandmark {
  public static void main(String[] args) {
    long start=System.currentTimeMillis();
    long mem1=Runtime.getRuntime().freeMemory();
    JT.connectDerby("test");
    String col="id INT NOT NULL GENERATED ALWAYS AS IDENTITY CONSTRAINT " +
                    "primary_key PRIMARY KEY,name VARCHAR(30)";
    System.out.println("建立資料表 users : " + JT.createTable("users",col));
    for (int i=0; i<5000; i++) {
      JT.runSQL("INSERT INTO users(name) VALUES('USER" + i + "')");
      }
    System.out.println("插入資料 : OK");
    for (int i=0; i<5000; i++) {
      JT.runSQL("DELETE FROM users");
      }
    System.out.println("刪除資料 : OK");
    System.out.println("刪除資料表 users : " + JT.dropTable("users"));
    JT.closeDB();
    long end=System.currentTimeMillis();
    long mem2=Runtime.getRuntime().freeMemory();
    System.out.println("耗費時間 : " + (end-start) + " ms");
    System.out.println("耗費記憶體 : " + (mem1-mem2) + " bytes");
    }
  }

執行三次結果 :

E:\Java\JT>java DerbyLandmark
建立資料表 users : true
插入資料 : OK
刪除資料 : OK
刪除資料表 users : true
耗費時間 : 281578 ms
耗費記憶體 : 10135448 bytes

E:\Java\JT>java DerbyLandmark
建立資料表 users : true
插入資料 : OK
刪除資料 : OK
刪除資料表 users : true
耗費時間 : 254437 ms
耗費記憶體 : 7158168 bytes

E:\Java\JT>java DerbyLandmark
建立資料表 users : true
插入資料 : OK
刪除資料 : OK
刪除資料表 users : true
耗費時間 : 281875 ms
耗費記憶體 : 11584512 bytes

Derby 平均耗時 270 秒, 使用記憶體 9MB, 簡直是龜速, 而且數據較不穩定.

最後是 MySQL, 測試程式如下 :

import java.sql.*;
import java.util.*;
public class MySQLLandmark {
  public static void main(String[] args) {
    long start=System.currentTimeMillis();
    long mem1=Runtime.getRuntime().freeMemory();
    JT.connectMySQL("test","root","mysql","localhost");
    String col="id INT NOT NULL AUTO_INCREMENT PRIMARY KEY," +
                     "name VARCHAR(30)";
    System.out.println("建立資料表 users : " + JT.createTable("users",col));
    for (int i=0; i<5000; i++) {
      JT.runSQL("INSERT INTO users(name) VALUES('USER" + i + "')");
      }
    System.out.println("插入資料 : OK");
    for (int i=0; i<5000; i++) {
      JT.runSQL("DELETE FROM users");
      }
    System.out.println("刪除資料 : OK");
    System.out.println("刪除資料表 users : " + JT.dropTable("users"));
    JT.closeDB();
    long end=System.currentTimeMillis();
    long mem2=Runtime.getRuntime().freeMemory();
    System.out.println("耗費時間 : " + (end-start) + " ms");
    System.out.println("耗費記憶體 : " + (mem1-mem2) + " bytes");
    }
  }

執行三次結果 :

E:\Java\JT>java MySQLLandmark
建立資料表 users : true
插入資料 : OK
刪除資料 : OK
刪除資料表 users : true
耗費時間 : 8688 ms
耗費記憶體 : 6042344 bytes

E:\Java\JT>java MySQLLandmark
建立資料表 users : true
插入資料 : OK
刪除資料 : OK
刪除資料表 users : true
耗費時間 : 8468 ms
耗費記憶體 : 6011544 bytes

E:\Java\JT>java MySQLLandmark
建立資料表 users : true
插入資料 : OK
刪除資料 : OK
刪除資料表 users : true
耗費時間 : 8640 ms
耗費記憶體 : 6011712 bytes

MySQL 平均 8.6 秒, 使用記憶體 6MB, 效能最優.

總之, 純 Java 打造的 Derby 效能實在慘不忍睹, 花的時間是 ACCESS 的 15 倍, MySQL 的 31 倍, 使用的記憶體是 ACCESS 的 6 倍, 所以只適合做測試練習用, 要用在公司專案簡直是噩夢. ACCESS 花的時間是 MySQL 的兩倍, 雖小輸 MySQL, 但還可接受, 堪用啦.


沒有留言 :