为什么 rows.Next() 取决于数据库响应率?

Why does rows.Next() depends on DB response rate?

我正在使用 sqlxpgxpostgresql。有两个数据库。首先 - 基于 VPS 服务器(慢的),其次 - 在我的电脑上安装 locally(快的)。我对这段代码有疑问:

var ordersSlice []OrdersModel    
start := time.Now()
query = `select * from get_all_orders();`
rows, err = db.Queryx(query)
log.Printf("Query time %s", time.Since(start)) // avg in slow DB - 62ms, avg in fast DB - 20ms

if rows == nil || err != nil {
    fmt.Println(err)
    fmt.Println("no result")
    response.WriteHeader(http.StatusInternalServerError)
    return
}

// db.Close() to check if rows.Next() depends on DB
start = time.Now()
for rows.Next() {
    var order OrdersModel

    err = rows.StructScan(&order)
    if err != nil {
        fmt.Println(err)
    }
    ordersSlice = append(ordersSlice, order)
}
log.Printf("Sturct scan time %s", time.Since(start)) // avg in slow DB - 14.4S, avg in fast DB - 9ms

我的意思是 rows.Next() 比使用慢数据库的 db.Queryx(query) 花费更多的时间。处理结果需要 14.4 秒。为什么这样? db.Queryx(query) 代码的第一部分应取决于数据库响应率。如我所见,db.Queryx(query) 应该取决于数据库响应率,因为查询是在这里执行的,结果放在 rows 中。而在 rows.Next() 中,结果只是在处理中。当我假设 rows.Next() 以某种方式依赖于 DB 时,我在 row.Next() 循环执行之前关闭了连接,以这种方式 db.Close()。但是没有错误。记录已处理。

循环for rows.Next()不与DB通信,为什么要依赖DB响应率?

简短的回答是:是的,Rows.Next() 与数据库通信。

来自 database/sql 文档:

Rows is the result of a query. Its cursor starts before the first row of the result set

但是,实际上,实现细节留给了数据库驱动程序。

例如在lib/pq, Query executes either simple query or extended query protocol (see postgres docs for more details) and after it receives RowDescription object, it parses it into internal structure(rowHeader). Then,rows.Next() uses it to fetch actual data.

你可以看到,pgx 做了类似的事情。 Query 方法 executes one of protocols 并将来自 RowDescription 的数据保存在 ResultReader 结构中。然后 rows.Next 使用它从数据库中获取数据。