Ali*_*xel 5 sqlite performance go database-performance
我有一个非常简单的查询,它返回几千行,只有两列:
SELECT "id", "value" FROM "table" LIMIT 10000;
Run Code Online (Sandbox Code Playgroud)
发出后sql.Query(),我使用以下代码遍历结果集:
data := map[uint8]string{}
for rows.Next() {
var (
id uint8
value string
)
if error := rows.Scan(&id, &value); error == nil {
data[id] = value
}
}
Run Code Online (Sandbox Code Playgroud)
如果我直接在数据库上运行完全相同的查询,我会在几毫秒内得到所有结果,但 Go 代码需要更长的时间才能完成,有时几乎需要 10 秒!
我开始注释掉代码的几个部分,看来这rows.Scan()就是罪魁祸首。
Scan 将当前行中的列复制到 dest 指向的值中。
如果参数的类型为 *[]byte,则 Scan 会在该参数中保存相应数据的副本。该副本归调用者所有,可以无限期修改和保留。可以通过使用 *RawBytes 类型的参数来避免复制;有关其使用限制,请参阅 RawBytes 的文档。如果参数的类型为 *interface{},则 Scan 会复制底层驱动程序提供的值而不进行转换。如果该值的类型为 []byte,则会创建一个副本,并且调用者拥有结果。
*[]byte如果我使用,*RawBytes或来代替,可以期望任何速度改进吗*interface{}?
查看代码,看起来该convertAssign()函数正在执行许多对于该特定查询来说不必要的操作。所以我的问题是:如何才能使这个Scan过程更快?
我考虑过重载函数以期望预定的类型,但这在 Go 中是不可能的......
有任何想法吗?
小智 4
是的,您可以使用RawBytes它来rows.Scan()避免内存分配/复制
关于convertAssign()功能 - 是的,它在 Go 1.2 中不是最佳的,但他们在 1.3 中做出了重大改进:
- http://code.google.com/p/go/issues/detail?id=7086
- 无锁同步实现。水池
我有一些使用示例RawBytes- https://gist.github.com/yvasiyarov/9911956
该代码从 MySQL 表中读取数据,进行一些处理并将其写入 CSV 文件。昨晚生成4GB CSV数据(约3000万行)耗时1分24秒
所以我很确定 go 代码之外有什么问题:更糟糕的是,rows.Scan()可能不会给你带来 10 秒的延迟。
| 归档时间: |
|
| 查看次数: |
3961 次 |
| 最近记录: |