登录
首页 >  Golang >  Go问答

如何让rows.Scan更高效?

来源:stackoverflow

时间:2024-04-12 20:45:33 453浏览 收藏

一分耕耘,一分收获!既然打开了这篇文章《如何让rows.Scan更高效?》,就坚持看下去吧!文中内容包含等等知识点...希望你能在阅读本文后,能真真实实学到知识或者帮你解决心中的疑惑,也欢迎大佬或者新人朋友们多留言评论,多给建议!谢谢!

问题内容

我有一个用 go 编写的 web 应用程序,该应用程序对 postgres 数据库进行查询。当我取回记录时,我使用 rows.next 迭代记录,并使用 rows.scan 将每一行扫描到一个结构。

如何才能使整个过程更快?

我认为这个程序效率不是很高,因为随着数据库的每一条新记录,扫描所有记录的时间也会增加。我想过使用 goroutine,但我担心也许两个 goroutine 会扫描相同的数据。我可以通过使用互斥体来防止这种情况吗?但是,如果我们使用互斥锁来阻止其他 goroutine 访问数据,那么使用并发还有什么意义呢?

这是我计划改进的代码:

func getusers() ([]publicuser, error) {
    query := `select user_id, first_name, last_name, registered_at from users;`
    rows, err := db.query(query)
    if err != nil {
        return nil, err
    }

    var us []publicuser

    for rows.next() {
        var u publicuser
        if err = rows.scan(&u.userid, &u.firstname, &u.lastname, &u.registeredat); err != nil {
            log.println(err, "getusers")
            return nil, err
        }
        us = append(us, u)
    }
    if err := rows.err(); err != nil {
        log.println(err, "getusers2")
        return nil, err
    }
    return us, nil
}

我应该像这样启动一个新的 goroutine 吗?:

func GetUsers() ([]publicUser, error) {
    query := `select user_id, first_name, last_name, registered_at from users;`
    rows, err := db.Query(query)
    if err != nil {
        return nil, err
    }

    var us []publicUser

    for rows.Next() {
        go func() {
             var u publicUser
             if err = rows.Scan(&u.UserId, &u.FirstName, &u.LastName, &u.RegisteredAt); err != nil 
             {
                 log.Println(err, "GetUsers")
                 return nil, err
             }
             us = append(us, u)
       }()
    }
    if err := rows.Err(); err != nil {
        log.Println(err, "GetUsers2")
        return nil, err
    }
    return us, nil
}

正确答案


人们一般通过分页来解决这个问题。基本思想是,客户端可以一次请求 n 条记录,并且每个后续请求都会返回 n 记录偏移量 n * i + 1 (其中 i 是您当前正在进行的循环迭代)。

例如,如果您通过前端 GUI 显示此用户列表,您可能希望有一个表一次显示 50 个结果,而不是整个数据库中的所有用户,因为这会减慢您的前端速度。每当用户单击查看下一页时,您都会向服务器发出新请求,请求 50 个结果,偏移 50(因为我们现在请求第 2 页)。这种方法解决了这种情况下的真正瓶颈,即数据库,而不是服务器代码。请参阅 this resource 了解更多信息。

另请参阅 this SO answer,了解对 SQL 查询结果进行分页的示例。

今天带大家了解了的相关知识,希望对你有所帮助;关于Golang的技术知识我们会一点点深入介绍,欢迎大家关注golang学习网公众号,一起学习编程~

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>