2 回答

TA貢獻1843條經(jīng)驗 獲得超7個贊
除了@mkopriva 在關(guān)于客戶端的評論中所說的內(nèi)容之外,使用準(zhǔn)備好的語句還有服務(wù)器端的影響。
重要的是要注意 using*sql.DB
使用連接池:
DB 是代表零個或多個底層連接池的數(shù)據(jù)庫句柄
為什么這很重要?那么并發(fā)訪問可能會觸發(fā)多個物理連接。并且當(dāng)使用準(zhǔn)備好的語句時——它們應(yīng)該被重用——只有在同一個數(shù)據(jù)庫會話(即連接)上使用時才有效。
連接池(使用*sql.DB
)本質(zhì)上不能保證這一點。因此,如果有 100 個并發(fā)查詢 - 理論上可能會生成 100 個并發(fā)數(shù)據(jù)庫連接 -不是一個 - 但在服務(wù)器端最多有 100 個準(zhǔn)備好的語句。
您可以通過sql.DB.Conn()獲得與數(shù)據(jù)庫的單個連接,其中:
在同一個 Conn 上運行的查詢將在同一個數(shù)據(jù)庫會話中運行。
這意味著任何先前生成的準(zhǔn)備好的語句都將獲得重用的好處(因為它們使用相同的“會話”)。
總之,權(quán)衡準(zhǔn)備好的語句對客戶端和服務(wù)器影響的好處,以及您是否真的通過并發(fā)使用獲得了這些好處。

TA貢獻1869條經(jīng)驗 獲得超4個贊
我花了更多時間進行測試和分析,所以這是我的發(fā)現(xiàn) - 也證實了@mkopriva 的評論。
如果使用SELECT
語句,無論是否使用查詢占位符,您都應(yīng)該更喜歡使用DB.Query
和/或DB.QueryRow
而不是DB.Prepare
&STMT.Exec
組合。DB.Query
當(dāng)我檢查 MySQL 查詢?nèi)罩緯r,它看起來就像DB.QueryRow
它們用于DB.Exec
沒有參數(shù)占位符的查詢一樣。這意味著只有一個( Query
) 網(wǎng)絡(luò)往返而不是三個( Prepare
,Execute
和Close
)!
那么為什么不直接使用DB.Exec
呢?因為它用于不返回結(jié)果集的查詢。順便說一句,DB.Exec
它直接釋放它的連接回池,但DB.Query
它的連接保持在池之外,直到rows.Close()
被調(diào)用。如果您忘記調(diào)用它,這可能會導(dǎo)致連接“泄漏”和連接不可用。因此,從技術(shù)上講,DB.Query
如果您沒有正確地做事,就會有其自身的風(fēng)險。
最后要注意的是,如果您的INSERT
,UPDATE
和DELETE
query 參數(shù)沒有 SQL 注入,那么請使用DB.Exec
else 來DB.Prepare
代替。對于手動準(zhǔn)備查詢參數(shù),您可以使用fmt.Sprintf()函數(shù)。
- 2 回答
- 0 關(guān)注
- 459 瀏覽
添加回答
舉報