惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Visual Studio Blog
U
Unit 42
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
The GitHub Blog
The GitHub Blog
Microsoft Azure Blog
Microsoft Azure Blog
有赞技术团队
有赞技术团队
Stack Overflow Blog
Stack Overflow Blog
爱范儿
爱范儿
博客园 - 司徒正美
Vercel News
Vercel News
I
InfoQ
GbyAI
GbyAI
C
Check Point Blog
B
Blog RSS Feed
Martin Fowler
Martin Fowler
B
Blog
MyScale Blog
MyScale Blog
腾讯CDC
博客园 - Franky
Blog — PlanetScale
Blog — PlanetScale
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Hugging Face - Blog
Hugging Face - Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 三生石上(FineUI控件)

博客园 - 程序员老刘

SaaS多租户改造Spring项目核心代码 windows11的vmware启动报错 MySQL8的root帐号授权 centrifugal 的IM消息服务历史消息报错 支持restart的启动脚本 golang strings.Split的疑问 golang的极简流式编程实现 golang 常用的日期方法和时区的坑 golang的多协程实践 golang redis的模式订阅 golang 实现并发计算文件数量 java开发的zimg客户端 CAS单点登录实践(spring cas client配置) 81进制,用多进制方式把一个长长的整数变短 chrome浏览器自动填充失效问题 spring 登录提示 Bad credentials spring 项目tomcat 8.0.2 发布报错:Could not initialize class org.hibernate.validator.engine.ConfigurationImpl spring tiles界面为空白 activiti部署到linux后流程图不显示汉字的问题
golang SQLite3性能测试
程序员老刘 · 2017-04-12 · via 博客园 - 程序员老刘

SQLite是个小型的数据库,很简洁,即支持文件也支持内存,比较适合小型的独立项目,在没有网络的时候做一些复杂的关系数据存储和运算。

为了考察性能做10M(1000万)条记录的测试,测试机4CPU、8G内存,操作系统:Ubuntu 16

测试结果:

10M条写入时间:92秒

平均每条检索时间:0.0172毫秒

最大内存占用1.7G

使用的Driver

github.com/mattn/go-sqlite3

下面是测试的代码

//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))