了解响应时间成本

时间:2019-06-04 15:16:46

标签: go clickhouse fasthttp

我是Golang的新手,正在尝试编写带有json响应的简单网络服务器。端点之一是用于数据库访问。对于类似静态的响应(例如任何静态字符串或简单的数据转换),平均响应时间约为0s(<1ms)。如果添加一些数据库请求,则平均时间最多增加250ms,而不取决于函数内容。因此,我试图了解此功能的时间。

我已经知道的:

  1. 查询数据库大约需要40-50毫秒
  2. 日期时间转换成本> 1毫秒
  3. json.Marshal花费<1毫秒
  4. string(json.Marshal) <1ms

我所有的问题都出在rows.Next()

  1. rows.Next()内部的所有内容分别花费<1毫秒
  2. 每个row.Next()过程的开销取决于行的长度,大约为10-50ms。

如果我理解db.Query()在一个请求中获取所有行并将其保留在内存中,以提供虚拟游标作为迭代器(.Next())。为什么要花这么多钱?

  1. 所有row.Next()数据处理大约需要180毫秒。 db.Query等于40毫秒,大约等于总响应时间(〜240毫秒)
  2. 如果我对所有row.Next()个周期进行注释,仅使db.Query的总响应时间仍在200-240毫秒之间,则

我使用的包裹:

import (
    "database/sql"
    "encoding/json"
    "fmt"
    "log"
    "os"
    "strconv"
    "time"
    "github.com/kshvakov/clickhouse"
    routing "github.com/qiangxue/fasthttp-routing"
    "github.com/valyala/fasthttp"
)
func getRecs(client string, dt string) string {
    dtT := transformDate(&dt)
    rows, err := db.Query(getRecsRequest(&client, &dtT))

    if err != nil {
        log.Fatal(err)
    }
    defer rows.Close()

    start := time.Now()

    got := []databaseRows{}
    elapsed := time.Since(start)
    for rows.Next() {
        elapsed = time.Since(start)
        log.Printf("Next took %s", elapsed)
        var r databaseRows
        err := rows.Scan(&r.ItemIds, &r.DtRecommendation, &r.Number)
        if err != nil {
            log.Fatal(err)
        }
        got = append(got, r)
        start = time.Now()
    }

    jsonData, err := json.Marshal(&got)
    return string(jsonData)
}
func getRecs(client string, dt string) string {
    dtT := transformDate(&dt)
    rows, err := db.Query(getRecsRequest(&client, &dtT))

    if err != nil {
        log.Fatal(err)
    }
    defer rows.Close()

    // start := time.Now()

    got := "[]databaseRows{}"
    // elapsed := time.Since(start)
    // for rows.Next() {
    //  elapsed = time.Since(start)
    //  log.Printf("Next took %s", elapsed)
    //  var r databaseRows
    //  err := rows.Scan(&r.ItemIds, &r.DtRecommendation, &r.Number)
    //  if err != nil {
    //      log.Fatal(err)
    //  }
    //  got = append(got, r)
    //  start = time.Now()
    // }

    jsonData, err := json.Marshal(&got)
    return string(jsonData)
}

我可以期望Web服务器的响应时间大约是数据库请求时间吗?

更新。

我用“ github.com/kshvakov/clickhouse”尝试了“ github.com/jmoiron/sqlx”,结果是一样的。仅语法已更改。

我还尝试了“ github.com/mailru/go-clickhouse”和“ database / sql”。它提供对HTTPhouse Clickhouse的访问。我按预期将所有行放在一个记录中,但是http请求花费了大约240ms的时间,数据处理花费了大约0ms的时间。因此,我正在寻找保持tcp连接打开的机会,以便能够在一个请求中获取所有nessasery行并进行工作与我的程序端内存缓冲区(与tcp / socket缓冲区结合使用时有一些缓冲区限制)。

更新2。

好吧,我已经尝试了本机Clickhouse客户端(以及其他此类DBeaver),大约250ms是此请求的限制。但这可能仅仅是Clickhouse本机tcp接口的限制。 但是40-50ms的db.Query()操作是什么,它不返回任何行。是在服务器端查询时间了吗?还是只是查询字符串检查?

0 个答案:

没有答案