web-dev-qa-db-ja.com

大規模なBLOB更新のためにMySQLを最適化する方法

大きなBLOB(最大10M)を保持するテーブルがあり、頻繁に更新されます。問題は、UPDATEステートメントの実行に最大1秒かかることがあり、アプリの設計により、これによりUIがブロックされることです。これらのUPDATE/INSERTステートメントを高速化する必要があります。 MySQLサーバー/ストレージエンジン/その他を調整することによってそれを行う方法はありますか?

問題のテーブルはInnoDBであり、私は圧縮を調整してみましたが、それほど大きな違いはないようです。クライアントはサーバーと同じマシン上にあるため、ネットワークのオーバーヘッドはありません。サーバーはMySQL 5.5です

2
rootkit

これはInnoDBアーキテクチャチューニングの仕事のようです!!!

InnoDB Architecture

BLOBデータはどこでInnoDBのボトルネックになりますか? 3か所

場所#1:InnoDBログファイル

InnoDBログファイルのサイズ( innodb_log_file_size で設定)は、更新される多くのトランザクションが書き込まれている場合にボトルネックになる可能性がありますBLOBデータ。

場所#2:InnoDBログバッファー

InnoDBログバッファー( innodb_log_buffer_size で設定)は、BLOB自体よりも小さい値を設定すると、ボトルネックになる可能性があります。デフォルトは8Mです。そのBLOBを持つ複数の行に対応するために、サイズを変更する必要がある場合があります。おそらく128Mから始めるのが良いでしょう。また、InnoDBログファイルに書き込む際のディスクI/Oを削減できます。

場所#3:MySQLパケット

MySQLパケットとは何ですか?

The Book によると

Understanding MySQL Internals

パラグラフ1〜3では、次のように説明しています。

MySQLネットワーク通信コードは、クエリが常に適度に短いため、MySQLではパケットと呼ばれる1つのチャンクでサーバーに送信および処理できるという前提で記述されています用語。サーバーは、パケットを格納するための一時バッファにメモリを割り当て、完全に収まるように要求します。このアーキテクチャでは、サーバーがメモリ不足になるのを防ぐための予防策が必要です。このオプションにより、パケットのサイズに上限が設けられます。

このオプションに関連するコードは、 sql/net_serv.cc にあります。 my_net_read()を確認してから、 my_real_read()への呼び出しに従い、 net_reallocに特に注意してください()

この変数は、多くの文字列関数の結果の長さも制限します。詳細については、 sql/field.cc およびsql/intem_strfunc.ccを参照してください。

MySQLデータの送信があるときはいつでも、MySQLパケットはMySQLデータをOSおよびネットワークに送信します。 InnoDBログバッファーと同様に、MySQLパケットも複数のBLOBに対応する必要があります。

エピローグ

過去にこのトピックについて話しました

警告

圧縮によって状況が少し悪化した可能性があります。どうして ?

InnoDBテーブルを圧縮すると、そのテーブルのデータページとインデックスページが読み取られるたびに、ページとページの非圧縮コピーがInnoDBバッファープールに共存します。テーブルを圧縮したままにする場合は、 InnoDBバッファープール(innodb_buffer_pool_sizeで設定) を展開する必要があります。私はこれと私の古い回答の更新について書きました: innodb_file_format Barracuda

2013-07-19 16:11 EST更新

あなたの最後のコメントに基づいて

最初の印象:InnoDBバッファーのチューニングは少しは役に立ちましたが、この特定のテーブルのバイナリログをオフにすることで、さらに改善が得られたようです。引き続きパフォーマンスを監視しています...

提案があります

他のMySQLコンポーネント(ibdata1、ib_logfile0、ib_logfile1、すべてのバイナリログ)を別のディスクにマウントできるように、すべての_.ibd_ファイルがデータボリューム上にあるようにInnoDBファイルを再設計する必要がある場合があります。これについては、PostgreSQLに関する投稿で以前に書いています: Postgres Write Performance on Intel S3700 SSD 、その質問をしている人は、パフォーマンスが10%向上したと言っています。

2013-07-26 15:33 EST更新

私が尋ねたので

質問:1)どのくらいRAMはDBサーバーにありますか?)2)SHOW VARIABLES LIKE 'innodb_file_per_table' ;;の結果は何ですか。 3)runSELECT SUM(data_length+index_length) FROM information_schema.tables WHERE engine='InnoDB';を実行すると何が得られますか?

そしてあなたは言った

8 GBのRAM、4 GBがMySQLで利用可能。 「innodb_file_per_table」、「ON」。 SUMは3316736000です

以下をお勧めします(まだ行っていない場合)。

試してみる !!!

4
RolandoMySQLDBA

1)複数の列があるテーブルの場合、BLOB列を使用しないクエリのメモリ要件を減らすために、BLOB列を別のテーブルに分割し、必要に応じて結合クエリで参照することを検討してください。

2)BLOB値を取得して表示するためのパフォーマンス要件は他のデータ型とは非常に異なる場合があるため、BLOB固有のテーブルを別のストレージデバイスまたは個別のデータベースインスタンスに置くこともできます。たとえば、BLOBを取得するには、SSDデバイスよりも従来のハードドライブに適した大容量のシーケンシャルディスク読み取りが必要になる場合があります。

この既存のSOリンクも参照できます https://stackoverflow.com/questions/5318961/optimizing-mysql-files-in-database-blob

1
Mahesh Patil