Почему 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 использует его для извлечения данных из БД.

Другие вопросы по тегам