Почему rows.Next() зависит от скорости ответа БД?
Я использую sqlx
, pgx
а также postgresql
. Есть две БД. Первый - на основе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. Как я вижу, этоdb.Queryx(query)
должен зависеть от скорости отклика БД, так как запрос выполняется здесь, а результаты помещаются в rows
. И вrows.Next()
, результаты просто обрабатываются. Когда я предположилrows.Next()
как-то зависит от БД, я закрыл соединение раньше row.Next()
выполнение цикла, таким образом db.Close()
. Но ошибки не было. Записи были обработаны.
Цикл for rows.Next()
не общаются с БД, так почему это зависит от скорости ответа БД?
1 ответ
Короткий ответ: ДА, Rows.Next()
общается с БД.
Из database/sql
документы:
Строки - это результат запроса. Его курсор начинается перед первой строкой набора результатов
Но на самом деле детали реализации оставлены драйверу БД.
Например, в lib/pq
, Query
выполняет либо простой запрос, либо протокол расширенного запроса (подробности см. в документации postgres) и после полученияRowDescription
объект, он разбирает его во внутреннюю структуру (rowHeader
). Затем,rows.Next()
использует его для получения фактических данных.
Ты это видишь pgx
делает нечто подобное. Query
метод выполняет один из протоколов и сохраняет данные изRowDescription
в ResultReader
состав. затемrows.Next
использует его для извлечения данных из БД.