Go语言使用各库插入最快的方法和查询最快的方法见:https://github.com/cvilsmeier/go-sqlite-bench
按照此测评项目,最快的插入方法是使用"github.com/cvilsmeier/sqinn-go/sqinn",通过调用其提供的辅助程序sqinn来进行插入。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
package main
import (
"fmt"
"math/rand"
"time"
"github.com/cvilsmeier/sqinn-go/sqinn"
)
type User struct {
ID int
Name string
Sex string
Age int
}
func main() {
sqinnpath := "path\\of\\sqinn.exe" // 下载地址https://github.com/cvilsmeier/sqinn/releases
dbname := "mydb.sqlite" // 实际的文件路径
// 启动 sqinn
sq := sqinn.MustLaunch(sqinn.Options{
SqinnPath: sqinnpath,
})
defer sq.Terminate()
// 打开数据库
sq.MustOpen(dbname)
defer sq.Close()
// 创建表
sq.MustExecOne("CREATE TABLE users (id INTEGER PRIMARY KEY NOT NULL, name VARCHAR, sex VARCHAR, age INT)")
// 随机生成用户信息
rand.Seed(time.Now().UnixNano())
totalRecords := 10000000 // 总用户数
cols := 4 // 每个用户的参数数量
Records := make([]any, cols*totalRecords)
for i := 0; i < totalRecords; i++ {
id := i + 1
name := fmt.Sprintf("User%d", id)
sex := []string{"Male", "Female"}[rand.Intn(2)]
age := rand.Intn(100) // 0-99 随机年龄
base := i * cols
Records[base] = id
Records[base+1] = name
Records[base+2] = sex
Records[base+3] = age
}
start := time.Now()
// 使用事务批量插入数据
sq.MustExecOne("BEGIN")
sq.MustExec("INSERT INTO users (id, name, sex, age) VALUES (?, ?, ?, ?)", totalRecords, cols, Records)
sq.MustExecOne("COMMIT")
duration := time.Since(start)
fmt.Println(duration, 10000000/int(duration.Seconds()))
// i5-12600K 上的输出为:
// Inser Cost Time: 7.3262848s
// Number Per Second: 1250000
// Number Per Second: 1428571 // 无主键的情况
}
|
Sqinn 是 SQLite C API 的替代方案。 Sqinn 读取来自 stdin 的请求, 将请求转发到 SQLite,并将响应写入 stdout。 它用于不允许调用 C API 函数的编程环境。
SQLite 数据库 是用C语言编写的,提供了在 C/C++ 中使用它的 API,它有许多语言绑定, 如果你不能或不想使用可用的语言绑定之一,并且您的编程语言允许创建子进程(fork/exec),一个选项可能是使用Sqinn通过 stdin/stdout 与 SQLite 进行通信。
一个例子是 Go :存在一堆 Go 库 用于读取和写入 SQLite 数据库, 他们大多数都使用 cgo 打电话给 SQLite C API 函数, 虽然这很有效(确实非常好),但它也有缺点:
- 您必须在开发系统上安装 gcc。
- cgo 减慢 Go 编译过程。
- 交叉编译cgo程序 另一个平台(比如从 Linux 到 MacOS)很难设置。
Sqinn 提供映射到 SQLite 函数的函数,例如 sqlite3_open(), sqlite3_prepare(), sqlite3_bind(), 等等。 如果您还没有阅读 SQLite C/C++ 简介接口 ,现在正是好时机。 花 5 分钟阅读并了解 SQLite 的基本工作原理。
在进程边界之间来回编组请求和响应当然很慢,为了提高性能,Sqinn 提供了一些函数,让您可以在一个请求 / 响应周期中调用多个 SQLite 函数。
所有函数调用和用于编组请求的二进制 IO 协议中描述 响应数据在 io_protocol.md 。
对于Go语言绑定,请参见 https://github.com/cvilsmeier/sqinn-go ,
有关基准测试,请参见 https://github.com/cvilsmeier/sqinn-go-bench 。
https://turriate.com/articles/making-sqlite-faster-in-go