golang SQLite3性能測試

SQLite是個小型的數據庫,很簡潔,即支持文件也支持內存,比較適合小型的獨立項目,在沒有網絡的時候作一些複雜的關係數據存儲和運算。git

爲了考察性能作10M(1000萬)條記錄的測試,測試機4CPU、8G內存,操做系統:Ubuntu 16github

測試結果:sql

10M條寫入時間:92秒數據庫

平均每條檢索時間:0.0172毫秒網絡

最大內存佔用1.7G性能

使用的Driver測試

github.com/mattn/go-sqlite3spa

下面是測試的代碼操作系統

//SQLite in memory,當心,不能只寫:memory:,這樣每一次鏈接都會申請內存
    db, err := sql.Open("sqlite3", "file::memory:?mode=memory&cache=shared&loc=auto")
    if err != nil {
        fmt.Println("SQLite:", err)
    }
    defer db.Close()
    fmt.Println("SQLite start")
    //建立表//delete from BC;,SQLite字段類型比較少,bool型能夠用INTEGER,字符串用TEXT
    sqlStmt := `create table BC (b_code text not null primary key, c_code text not null, code_type INTEGER, is_new INTEGER);`
    _, err = db.Exec(sqlStmt)
    if err != nil {
        fmt.Println("create table error->%q: %s\n", err, sqlStmt)
        return
    }
    //建立索引,有索引和沒索引性能差異巨大,根本就不是一個量級,有興趣的能夠去掉試試
    _, err = db.Exec("CREATE INDEX inx_c_code ON BC(c_code);")
    if err != nil {
        fmt.Println("create index error->%q: %s\n", err, sqlStmt)
        return
    }
    //寫入10M條記錄
    start := time.Now().Unix()
    tx, err := db.Begin()
    if err != nil {
        fmt.Println("%q", err)
    }
    stmt, err := tx.Prepare("insert into BC(b_code, c_code, code_type, is_new ) values(?,?,?,?)")
    if err != nil {
        fmt.Println("insert err %q", err)
    }
    defer stmt.Close()
    var m int = 1000 * 1000
    var total int = 10 * m
    for i := 0; i < total; i++ {
        _, err = stmt.Exec(fmt.Sprintf("B%024d", i), fmt.Sprintf("C%024d", i), 0, 1)
        if err != nil {
            fmt.Println("%q", err)
        }
    }
    tx.Commit()
    insertEnd := time.Now().Unix()
    //隨機檢索10M次
    var count int64 = 0

    stmt, err = db.Prepare("select b_code, c_code, code_type, is_new from BC where c_code = ? ")
    if err != nil {
        fmt.Println("select err %q", err)
    }
    defer stmt.Close()
    bc := new(BCCode)
    for i := 0; i < total; i++ {

        err = stmt.QueryRow(fmt.Sprintf("C%024d", i)).Scan(&bc.B_Code, &bc.C_Code, &bc.CodeType, &bc.IsNew)
        if err != nil {
            fmt.Println("query err %q", err)
        }
        //屏幕輸出會花掉好多時間啊,計算耗時的時候仍是關掉比較好
        //fmt.Println("BCode=", bc.B_Code, "\tCCode=", bc.C_Code, "\tCodeType=", bc.CodeType, "\tIsNew=", bc.IsNew)
        count++
    }
    readEnd := time.Now().Unix()
    fmt.Println("insert span=", (insertEnd - start),
        "read span=", (readEnd - insertEnd),
        "avg read=", float64(readEnd-insertEnd)*1000/float64(count))
相關文章
相關標籤/搜索