首頁 > 後端開發 > Golang > 主體

為什麼Go中的database/sql比直接資料庫查詢慢,我該如何解決?

Mary-Kate Olsen
發布: 2024-11-17 13:57:02
原創
664 人瀏覽過

Why is database/sql in Go Slower Than Direct Database Querying, and How Can I Fix It?

調查查詢效能差異:資料庫/sql 與直接查詢

使用Go 資料庫/sql 套件執行的查詢比直接針對資料庫執行的等效查詢慢得多。為了解決這種差異,必須深入研究底層機制。

database/sql 中的連線管理

sql.DB 物件代表一個連線池,而不是單一連線。當呼叫 sql.Open 時,它會初始化池,但可能不會建立任何連線。僅當請求查詢時,才會建立新連線。

對查詢計時的影響

在提供的程式碼片段中,第一個查詢遇到效能影響,因為它觸發了新連接的建立資料庫連線。由於缺乏連接重用,第二個查詢也表現出效能差距。每個查詢都會建立一個新連接,而不是利用池中現有的空閒連接。

將連線釋放回池

要解決此問題,將連線釋放回池至關重要每次查詢後。這可以透過保留 db.Query 的第一個傳回值(代表查詢結果)並對其呼叫 .Close() 來實現。

建立空閒連接

從池中的可用連接,在初始化後對 sql.DB 物件呼叫 Ping。這將強制建立初始連線。

準備好的語句和位置參數

當查詢包含參數時使用準備好的語句。 Postgres 協定支援參數,而不是直接將值插入查詢字串中。這種單獨的參數化可以更有效地處理查詢。

程式碼範例

以下程式碼片段說明如何正確管理連接和重複使用準備好的語句:

package main

import (
    "database/sql"
    "fmt"
    _ "github.com/lib/pq"
    "time"
)

func main() {
    // Initialize database connection with initial idle connection
    db, err := sql.Open("postgres", "postgres:///?sslmode=disable")
    if err != nil {
        panic(err)
    }
    if err := db.Ping(); err != nil {
        panic(err)
    }

    for i := 0; i < 5; i++ {
        // Prepare query
        query := "select 1 where true"
        stmt, err := db.Prepare(query)
        if err != nil {
            panic(err)
        }

        // Execute and time query
        firstQueryStart := time.Now()
        rows, err := stmt.Query()
        firstQueryEnd := time.Now()
        if err != nil {
            panic(err)
        }

        // Release connection back to pool
        rows.Close()

        fmt.Println(fmt.Sprintf("query #%d took %s", i, firstQueryEnd.Sub(firstQueryStart).String()))
    }
}
登入後複製

透過實作這些最佳化,可以顯著縮小查詢效能差距,提供與直接查詢相當的執行時間。

以上是為什麼Go中的database/sql比直接資料庫查詢慢,我該如何解決?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板