2016-11-02 3 views
0

ログを保存するフィールドがあるMEDIUMTEXTのテーブルがあります。
次のように私は、ログにデータを追加している:短いログの場合読んでいないMySQL CONCAT

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に対応しています)。必要に応じてnly(抽出)。

ダイジェストに含まれている最後のエントリのインデックスとともに一時的な連結(つまり、抽出時に作成される)を格納するDIGESTテーブルを持つことで、この機能を拡張することもできます。次に、アイテムの「全文」を表示する場合は、最初に消化されたテキストを抽出し、最後に消化された値が記録された後に登録されたものを追加します(もちろん、DIGESTテーブルを最新の完全連結された結果)。

+0

単純に1,2,3よりも悪いです。古い行を削除し、新しい大きな行にスペースを割り当てる必要があります。 –

+0

私はあなたのコメントを理解している@RickJamesを確認していません。パフォーマンスの問題は、各INSERTで発生する連結から発生します。各SELECTにはINSERTSが非常に多いという前提で、提案された方法でパフォーマンスが確実に向上します(これは過去に行っており、改善は非常に有意でした)。私があなたを完全に誤解した場合は、明確にしてください。 – FDavidov

+0

異なったフレーズ - ステップ#3は、表面に現れるよりもコストがかかります。記憶域(InnoDBのブロック、MyISAMのストリーム)のために、新しい大きな行を格納すると、ブロック分割や他の「コストのかかる」アクションが発生することがあります。 (私達は合意に達しており、私はあなたの答えが好きです。) –

関連する問題