rows.Scan()的性能,我有一個返回幾千行,只有兩列的非常簡單的查詢:提高圍棋
SELECT "id", "value" FROM "table" LIMIT 10000;
發行sql.Query()
後,我遍歷結果有以下設置代碼:
data := map[uint8]string{}
for rows.Next() {
var (
id uint8
value string
)
if error := rows.Scan(&id, &value); error == nil {
data[id] = value
}
}
如果我直接在數據庫上運行完全相同的查詢,我得到的所有結果幾毫秒之內復出,但Go代碼需要更長的時間完成,有時10秒左右!
我開始註釋代碼的幾個部分,它似乎是rows.Scan()
是罪魁禍首。
掃描將當前行中的列複製到dest所指向的值 處。
如果參數的類型爲* []字節,則掃描在該參數中保存對應數據的副本 。該副本由主叫方擁有,可以修改並保留無限期地 。可以通過使用類型* RawBytes的 參數來避免該副本;請參閱RawBytes 的文檔以瞭解其使用限制。如果參數的類型爲* interface {},則 掃描會複製由底層驅動程序提供的值,而不會使用 轉換。如果該值是[]字節類型,則進行復制並且調用者擁有結果。
任何能想到的任何速度的提高,如果我使用*[]byte
,*RawBytes
或*interface{}
呢?
看着the code,它看起來像convertAssign()
function做了很多東西,這是不需要這個特定的查詢。所以我的問題是:我怎樣才能使Scan
過程更快?
我想過超載期望預定類型的功能,但是這是不可能去...
任何想法?
當您嘗試使用'* [] byte','* RawBytes'和'* interface {}'時發生了什麼? – peterSO
@peterSO:當我讀取'* RawBytes'的文檔和數據時,只要您調用'rows.Next()'就會消失。我還沒有嘗試過其他兩個,我只是問它是否會對任何事情有所幫助。如果你看看'convertAssign'源代碼(在答案中鏈接),'uint8'類型仍然需要進行思考。 –
您是否嘗試使用分析器來幫助縮小範圍? –