2016-11-02 50 views
0

我有一個表,其中包含MEDIUMTEXT字段用於存儲日誌。
我將數據添加到日誌如下:MySQL CONCAT without reading

UPDATE tbl SET log = CONCAT(log, 'newtext') 

對於短原木它工作正常,但隨着時間的推移,日誌區域變大,它會減慢成倍。看起來,MySQL讀取整個領域,然後寫出整個事情。

如何將數據添加到日誌中而不會影響性能?如果沒有辦法做到這一點,我該如何存儲和更新如此大塊的文本數據?

回答

1

如果你想一想,這是很明顯的是,引擎將:

1 - Retrieve the existing value of `log`, 
2 - Concatenate the retrieved value with the new one, 
3 - Store the result of "2" back in the same row. 

因爲(我猜(在實踐中,在短手形式執行此)

這裏),如果你想檢查日誌(這個日誌的發生頻率比添加信息的頻率要低得多),你需要整個鏈接,只有,我建議將信息存儲在單獨的記錄中(帶有一個關鍵列對應於您正在收集日誌的特定ITEM)並進行連接o需要時(提取)。

您甚至可以通過使用一個DIGEST表來存儲臨時級聯(即,在提取時創建)以及包含在摘要中的最後一個條目的索引,從而加強這一點。然後,無論何時您希望查看該項目的「完整故事」,您都會首先提取已消解的文本,然後追加記錄最後一個消解值後記錄的任何內容(當然,還要更新最新的DIGEST表格連結結果)。

+0

它比簡單的1,2,3更糟糕 - 必須刪除舊行併爲新的更大的行分配空間。 –

+0

不知道@RickJames,我瞭解您的評論。性能問題來自於每個INSERT中的連接。假設每個SELECT都有很多INSERTS,所提出的方法肯定會提高性能(過去我已經這樣做了,而且改進非常顯着)。如果我完全誤解了你,請澄清。 – FDavidov

+0

換言之 - 步驟#3比表面上看起來更昂貴。由於存儲(InnoDB的塊,MyISAM的流),存儲新的更大的行可能會導致塊分割和其他「昂貴」的操作。 (我們達成了協議,我喜歡你的回答。) –