我試圖在一個「事務」中插入很多(從數十到數百)類似的記錄到一個表中。記錄僅因主鍵和另外一個字段而有所不同。該表是一個MEMORY表,插入的記錄經常更新並經常刪除,但有些可以留在表中一天。表結構:向MySQL高效地插入很多類似的記錄
id BIGINT
sid CHAR
pid INT
mask INT
param1 INT
param2 INT
... INT
paramN INT
PRIMARY (id, sid),
KEY [BTREE] (sid), (param1), (param2), (...), (paramN)
眼下插入發生過一份準備好的聲明:
INSERT INTO object_subscriptions (id, sid, pid, mask, ...)
VALUES (:id, :sid, :pid, :mask, ...)
ON DUPLICATE KEY UPDATE mask = mask | VALUES(mask)
記錄樣本:
13194140000467 | 'fBF8OfQlAjSS8uXsAAzx' | 7 | 22 | 3 | 0 | 188 | 5123 | 1
18392199238192 | 'fBF8OfQlAjSS8uXsAAzx' | 7 | 22 | 3 | 0 | 188 | 5123 | 1
26342478965721 | 'fBF8OfQlAjSS8uXsAAzx' | 7 | 22 | 3 | 0 | 188 | 5123 | 1
64322445645318 | 'fBF8OfQlAjSS8uXsAAzx' | 7 | 22 | 3 | 0 | 188 | 5123 | 1
13194140000467 | 'n2pFykYGNnsp-JfCAeJO' | 5 | 97 | 1293 | 0 | 188 | 5123 | 0
18392199238192 | 'n2pFykYGNnsp-JfCAeJO' | 5 | 97 | 1293 | 0 | 188 | 5123 | 0
26342478965721 | 'n2pFykYGNnsp-JfCAeJO' | 5 | 97 | 1293 | 0 | 188 | 5123 | 0
64322445645318 | 'n2pFykYGNnsp-JfCAeJO' | 5 | 97 | 1293 | 0 | 188 | 5123 | 0
這在幾十每批次記錄的偉大工程。每批有數百個,大幅減速。一個顯而易見的優化可以使性能提高一倍或三倍,即在一個語句中有多個VALUE集合,但這仍然留下發送N params
以及sid
和pid
與每條記錄的開銷,即使只有id
和mask
在一個批量。
我在考慮在準備好的語句中包含這些「固定」值,但是這些'params'是從用戶輸入生成的,並且不可信。由於數據發生變化的頻率以及需要執行多少次索引查找,我對MySQL和MEMORY存在困惑。否則,我會規範化數據或將所有內容移至鍵值存儲。
你可以將它寫入文件並使用'LOAD DATA INFILE'? – Barmar
我可以想到避免重複常見元素的方法,但它們最終會變得非常冗長,所以它可能無法真正解決問題。 – Barmar
@Barmar對於只有幾十條記錄的批處理來說,訪問文件系統的開銷可能太大。無論如何,MySQL服務器可能會或可能不在本地主機上,因此寫入文件並不總是一種選擇。此外,文件本身必須全部讀取,讀取所有重複值。但是,連續讀取文件比從外部客戶端一個接一個地發送準備好的語句要快得多。 – Xeos