[英]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.