Почему rows.Next () зависит от скорости отклика БД? - PullRequest
0 голосов
/ 29 марта 2020

Я использую sqlx, pgx и postgresql. Есть две БД. Первый - на базе VPS сервера (медленный), второй - на моем P C (быстрый) установлен 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 se c. Почему так? Первая часть кода с db.Queryx(query) должна зависеть от скорости отклика в дБ. Как я вижу, это db.Queryx(query) должно зависеть от скорости отклика в дБ, поскольку запрос выполняется здесь, а результаты помещаются в rows. А в rows.Next() результаты просто обрабатываются. Когда я предположил, что rows.Next() как-то зависит от БД, я закрыл соединение до выполнения row.Next() l oop, таким образом db.Close(). Но ошибки не было. Записи обработаны.

Цикл for rows.Next() не связывается с БД, так почему это зависит от скорости отклика БД?

1 Ответ

2 голосов
/ 29 марта 2020

Краткий ответ: ДА, Rows.Next() связывается с БД.

Из database/sql документов:

Строки - это результат запроса. Его курсор начинается перед первой строкой набора результатов

Но, на самом деле, детали реализации оставлены драйверу БД.

Например, в lib/pq, Query выполняет простой запрос или протокол расширенного запроса (подробнее см. postgres docs ) и после него получает RowDescription объект, он разбирает его на внутреннюю структуру (rowHeader). Затем rows.Next() использует его для извлечения фактических данных .

Вы можете видеть, что pgx делает нечто подобное. Query метод выполняет один из протоколов и сохраняет данные из RowDescription в ResultReader структуре. Затем rows.Next использует его для извлечения данных из БД.

...