RammusXu / rammusxu.github.io

My profile
https://rammusxu.github.io/
2 stars 0 forks source link

Mysql Batch Insert Test #57

Closed RammusXu closed 7 years ago

RammusXu commented 7 years ago

結論

實驗方法

打開 Ebean logger

在 logback.xml 加入

  <logger name="org.avaje.ebean.SQL" level="TRACE" />

2017-04-06 2 35 09

Test Case 定義

  1. callApi() 測試該 API 需要多久時間完成
  2. 每一個 @Test 之前都要先清除該 table (在這個測試使用 Receipt 這個 Model 為例)
  3. 第一次呼叫 API 都會需要比較長的時間
    • 不確定是否因為 Play 的 Action 第一次被呼叫需要比較多時間初始化, 或是因為第二次呼叫 API 有 keep-alive 所以 response 時間較短
    • 所以每個 @Test 的第一次 callApi() 的數值先忽略不計
  4. 為了測試資料庫已存在多筆資料是否影響 insert 速度, 所以沒有每次執行完 callApi() 都清除資料庫
    
    package models;

import com.avaje.ebean.Ebean; import controllers.TestUtils; import org.junit.Test; import play.Logger; import play.test.WithApplication;

import java.io.UnsupportedEncodingException; import java.util.Calendar;

public class Bean extends WithApplication { static final String URL_BASIC = "/testBean"; static final String URL_BATCH = "/testBeanBatch"; static final String URL_TRANS = "/testBeanTrans";

private void callApi(String url) throws UnsupportedEncodingException {
    long start = Calendar.getInstance().getTimeInMillis();
    TestUtils.get(url);
    long end = Calendar.getInstance().getTimeInMillis();
    Logger.debug("end - start = " + String.valueOf(end - start));
}

@Test
public void testTran() throws UnsupportedEncodingException {
    Logger.debug("testTran()");
    Ebean.createSqlUpdate("delete from receipt").execute();
    callApi(URL_TRANS);
    callApi(URL_TRANS);
    callApi(URL_TRANS);
}

@Test
public void testBatch() throws UnsupportedEncodingException {
    Logger.debug("testBatch()");
    Ebean.createSqlUpdate("delete from receipt").execute();
    callApi(URL_BATCH);
    callApi(URL_BATCH);
    callApi(URL_BATCH);
}

@Test
public void testBasic() throws UnsupportedEncodingException {
    Logger.debug("testBasic()");
    Ebean.createSqlUpdate("delete from receipt").execute();
    callApi(URL_BASIC);
    callApi(URL_BASIC);
    callApi(URL_BASIC);
}

}


### API 定義
1. bean() 不使用 `@Transactional`
2. beanTrans() 使用 `@Transactional`
3. beanBatch() 使用 `@Transactional`, 並使用 BatchMode
4. 每個 API 都是 Insert 1000 筆資料
```java

    public Result bean() {
        for (int i = 0; i < 1000; i++) {
            new Receipt(new Auth(0)).save();
        }
        return ok();
    }

    `@Transactional`
    public Result beanTrans() {
        for (int i = 0; i < 1000; i++) {
            new Receipt(new Auth(0)).save();
        }
        return ok();
    }

    public Result beanBatch() {
        Transaction txn = Ebean.beginTransaction();
        try {
            txn.setBatchMode(true);
            txn.setBatchSize(100);
            // ** turn off getGeneratedKeys if you don't need to use the
            // mymodel bean instances after you have inserted them **
            txn.setBatchGetGeneratedKeys(false);

            for (int i = 0; i < 1000; i++) {
                new Receipt(new Auth(0)).save();
            }

            txn.commit();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            txn.end();
        }
        return ok();
    }

實驗結果

Test 1 測試三種 API 的結果

[debug] application - testBatch() [debug] application - end - start = 1211 [debug] application - end - start = 1079 [debug] application - end - start = 1237 [debug] application - end - start = 1131 [debug] application - end - start = 1163

[debug] application - testTran() [debug] application - end - start = 1564 [debug] application - end - start = 1207 [debug] application - end - start = 1017 [debug] application - end - start = 1083 [debug] application - end - start = 1140


### Test 2 測試 setBatchMode, setBatchSize() 是否有用
- 在 API 中加入 Logger

```java
Logger.debug("getBatchSize = " + Ebean.currentTransaction().getBatchSize());
Logger.debug("getBatch = " + Ebean.currentTransaction().getBatch());
[debug] application - testBatch()
[debug] application - getBatchSize = 100
[debug] application - getBatch = ALL
[debug] application - end - start = 1620
[debug] application - getBatchSize = 100
[debug] application - getBatch = ALL
[debug] application - end - start = 1372
[debug] application - getBatchSize = 100
[debug] application - getBatch = ALL
[debug] application - end - start = 1198
[debug] application - getBatchSize = 100
[debug] application - getBatch = ALL
[debug] application - end - start = 1087
[debug] application - getBatchSize = 100
[debug] application - getBatch = ALL
[debug] application - end - start = 958

[debug] application - testTran()
[debug] application - getBatchSize = -1
[debug] application - getBatch = NONE
[debug] application - end - start = 1634
[debug] application - getBatchSize = -1
[debug] application - getBatch = NONE
[debug] application - end - start = 1230
[debug] application - getBatchSize = -1
[debug] application - getBatch = NONE
[debug] application - end - start = 1163
[debug] application - getBatchSize = -1
[debug] application - getBatch = NONE
[debug] application - end - start = 1065
[debug] application - getBatchSize = -1
[debug] application - getBatch = NONE
[debug] application - end - start = 982

~Test 3 測試 Batch Mode 的影響~

[debug] application - testBatch()
[debug] application - end - start = 13671
[debug] application - end - start = 10091
[debug] application - end - start = 8635
[debug] application - end - start = 8594
[debug] application - end - start = 9293
[debug] application - end - start = 12716
[debug] application - end - start = 10084
[debug] application - end - start = 8571
[debug] application - end - start = 10006
[debug] application - end - start = 10800
[debug] application - end - start = 10127
[debug] application - total = 98917

[debug] application - testTran()
[debug] application - end - start = 13457
[debug] application - end - start = 10823
[debug] application - end - start = 10583
[debug] application - end - start = 10794
[debug] application - end - start = 11090
[debug] application - end - start = 11087
[debug] application - end - start = 11027
[debug] application - end - start = 10616
[debug] application - end - start = 10412
[debug] application - end - start = 10621
[debug] application - end - start = 9022
[debug] application - total = 106075

Test 4 測試 Batch Size 的影響

[debug] application - testBatch()
[debug] application - end - start = 11677
[debug] application - end - start = 9143
[debug] application - end - start = 9899
[debug] application - end - start = 8678
[debug] application - end - start = 8264
[debug] application - end - start = 8362
[debug] application - end - start = 9611
[debug] application - end - start = 9540
[debug] application - end - start = 8665
[debug] application - end - start = 8859
[debug] application - end - start = 8812
[debug] application - total = 89833

[debug] application - testBatch500()
[debug] application - end - start = 8929
[debug] application - end - start = 11508
[debug] application - end - start = 9512
[debug] application - end - start = 8602
[debug] application - end - start = 9509
[debug] application - end - start = 11985
[debug] application - end - start = 9493
[debug] application - end - start = 9791
[debug] application - end - start = 9604
[debug] application - end - start = 9201
[debug] application - end - start = 9055
[debug] application - total = 98260

[debug] application - testBatch10()
[debug] application - end - start = 13276
[debug] application - end - start = 11663
[debug] application - end - start = 9911
[debug] application - end - start = 10153
[debug] application - end - start = 9608
[debug] application - end - start = 10827
[debug] application - end - start = 10407
[debug] application - end - start = 9903
[debug] application - end - start = 13279
[debug] application - end - start = 9854
[debug] application - end - start = 12044
[debug] application - total = 107649

Test 5 觀察 Transaction Log

trans transaction log batch transaction log

[debug] o.a.ebean.SQL - txn[1004] insert into receipt (receipt_id, brand_id, name, is_master, is_enable, modify_log_uuid) values (?,?,?,?,?,?); --bind(6728e074-893c-4ec6-8204-f307f22bfaa7,0,null,false,false,null,)
[debug] o.a.ebean.SQL - txn[1004] insert into receipt (receipt_id, brand_id, name, is_master, is_enable, modify_log_uuid) values (?,?,?,?,?,?); --bind(e69ecc8e-e18c-4d8d-8e70-3318e3766f1c,0,null,false,false,null,)
[debug] o.a.ebean.SQL - txn[1004] insert into receipt (receipt_id, brand_id, name, is_master, is_enable, modify_log_uuid) values (?,?,?,?,?,?); --bind(e7a3208b-3140-4105-be9c-225690d1345c,0,null,false,false,null,)
[debug] o.a.ebean.SQL - txn[1004] insert into receipt (receipt_id, brand_id, name, is_master, is_enable, modify_log_uuid) values (?,?,?,?,?,?); --bind(e346f8d9-2057-46de-b357-8937ad70b15b,0,null,false,false,null,)
[debug] o.a.ebean.SQL - txn[1004] insert into receipt (receipt_id, brand_id, name, is_master, is_enable, modify_log_uuid) values (?,?,?,?,?,?); --bind(940760c9-3ef5-465f-aa62-6565664645aa,0,null,false,false,null,)
[debug] o.a.ebean.SQL - txn[1004] insert into receipt (receipt_id, brand_id, name, is_master, is_enable, modify_log_uuid) values (?,?,?,?,?,?); --bind(147ffa27-4363-4749-b965-58fd7bc74f2c,0,null,false,false,null,)
[debug] o.a.ebean.SQL - txn[1004] insert into receipt (receipt_id, brand_id, name, is_master, is_enable, modify_log_uuid) values (?,?,?,?,?,?); --bind(d9f1c3da-5b8e-4b2b-886c-9002a77063ec,0,null,false,false,null,)