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

減少執行大事務時的記憶體消耗

WBOY
發布: 2024-02-10 23:06:08
轉載
513 人瀏覽過

減少執行大事務時的記憶體消耗

php小編柚子今天為大家介紹一個重要的技巧-如何減少執行大事務時的記憶體消耗。在處理大量資料或執行複雜操作時,記憶體消耗可能成為一個嚴重的問題。為了解決這個問題,我們需要採取一些最佳化措施,以提高程式碼的效率和效能。本文將為您詳細介紹一些減少記憶體消耗的方法和技巧,幫助您在處理大事務時更有效率地利用記憶體資源。

問題內容

我按照 internet 上的範例,使用以下 sqlite 參數提高了 insert 查詢的速度:

pragma journal_mode = off;
pragma synchronous = 0;
pragma cache_size = 1000000;
pragma locking_mode = exclusive;
pragma temp_store = memory;
登入後複製

這是我的程式碼:

tx, err := db.begin()
if err != nil {
    log.fatal(err)
}
pr, err := tx.prepare("insert into table (p1, p2, p3, p4, p5) values (?, ?, ?, ?, ?)")
if err != nil {
    log.fatal(err)
}
defer pr.close()
for i := 0; i < maxi; i++ {
    for j := 0; j < maxj; j++ {
        ...
        _, err = pr.exec(param1, param2, param3, param4, param5)
        if err != nil {
            log.fatal(err)
        }
    }
}
err = tx.commit()
if err != nil {
    log.fatal(err)
}
登入後複製

現在查詢運行速度很快,但消耗了太多 ram。因為資料儲存在ram中,只有在執行的最後才保存到資料庫檔案中。

我認為可以定期將資料保存到資料庫檔案中,這樣會稍微增加執行時間,但會減少記憶體消耗。隨著「i」的每次變化,交易開始,當所有「j」完成時,交易結束:

for i := 0; i < maxI; i++ {
    tx, err := db.Begin()
    if err != nil {
        log.Fatal(err)
    }
    pr, err := tx.Prepare("INSERT INTO Table (p1, p2, p3, p4, p5) VALUES (?, ?, ?, ?, ?)")
    if err != nil {
        log.Fatal(err)
    }
    defer pr.Close()
    for j := 0; j < maxJ; j++ {
        ...
        _, err = pr.Exec(param1, param2, param3, param4, param5)
        if err != nil {
            log.Fatal(err)
        }
    }
    err = tx.Commit()
    if err != nil {
        log.Fatal(err)
    }
}
登入後複製

我認為現在資料應該以區塊的形式寫入文件,並且 ram 中應該只有一個資料區塊。

但在執行過程中,資料並沒有儲存到檔案中,ram持續被填滿。也就是說,第一個和第二個程式碼選項的執行沒有差別。

我認為當調用事務的“commit”時,資料應該保存到檔案中,並且應該清除ram。請告訴我我做錯了什麼。

解決方法

PRAGMAcache_size的參數是頁數(一般為每頁4k位元組)。

PRAGMA cache_size = 1000000;將分配最大4GB的RAM給頁面快取。 頁面快取在需要時分配,最多可達最大值,但在連線關閉之前不會釋放。

由於您要插入大量行,它們最終會出現在不同的頁面上,因此您最終將在快取中保留已寫入磁碟的所有頁面,直到填滿快取為止。

如果您想減少記憶體消耗,只需將該值減少到 1000 之類的值(相當於 4 MB),或乾脆將其刪除。預設快取為 2 MB,如果您只是插入行就足夠了。

另請注意,當您呼叫 COMMIT 時(或如果沒有足夠的緩存,甚至在提交之前),資料確實會寫入磁碟。但是 Sqlite 會在快取中保留一個副本,以備以後需要時使用,以避免從磁碟重新讀取它。

以上是減少執行大事務時的記憶體消耗的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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