簡體   English   中英

如何讓 rows.Scan 更有效率?

[英]How to make rows.Scan more efficient?

我有一個用 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 頁)。 這種方法解決了這種情況下的真正瓶頸,即您的數據庫,而不是您的服務器代碼。 有關更多信息,請參閱此資源

列表 collections 應該支持分頁,即使結果通常很小。

另請參閱此 SO 答案,以獲取從 SQL 查詢中分頁結果的示例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM