web-dev-qa-db-ja.com

InnoDB挿入の高速化

私は大学院生で、OLAPを研究しています。そのため、初期ロードでInnoDB(MySQL 5.5)にデータをより速く挿入したいと考えています。この環境では、唯一のユーザーは私です。挿入速度をもっと緩やかに設定できると思いますが、現在は以下のテクニックを使っています。

  • 無効にするlog_bin
  • 有効にするskip-innodb-doublewrite
  • transaction_isolationREAD-COMMITTEDまたはREAD-UNCOMMITTEDに設定します(実際にはREAD-COMMITED
  • innodb_flush_log_at_trx_commit0または2に設定します(実際には0
  • innodb_buffer_pool_sizeを5GBに設定します(システムには6GBのRAMがあります)

InnoDBに高速に挿入するためのテクニックは他にありますか?また、innodb_io_read_threadinnodb_io_write_threadを変更する必要がありますか?さらに詳しい情報が必要な場合はお知らせください。

8
inohiro

提案#1

マシンに複数のコアがある場合は、次の値を増やす必要があります。

[mysqld]
innodb_read_io_threads = 64
innodb_write_io_threads = 64
innodb_io_capacity = 5000

これは何?

  • innodb_read_io_threads -InnoDBでの読み取り操作のI/Oスレッドの数。
  • innodb_write_io_threads -InnoDBでの書き込み操作のI/Oスレッドの数。
  • innodb_io_capacity -バッファープールからのページのフラッシュや挿入バッファーからのデータのマージなど、InnoDBバックグラウンドタスクによって実行されるI/Oアクティビティの上限。

提案#2

システムテーブルスペース(ibdata1)からデータとインデックスを分離するには、InnoDBの完全な再構築を実行する必要があります。複雑に聞こえますが、非常に簡単です。私はこれについて DBA StackExchange(Aug 29、2012)StackOverflow(2010年10月29日) 。基本的な手順は

  • SET GLOBAL innodb_fast_shutdown = 0;を実行します
  • mysqldumpですべてのデータをSQLダンプ
  • service mysql stop
  • 次のファイルを削除します
    • ibdata1
    • ib_logfile0
    • ib_logfile1
  • service mysql start

service mysql startを実行する前に、この行をmy.cnfに追加します

innodb_open_files=32768

これにより、個々のテーブルに専用のファイルハンドルができます。デフォルトは300です。 ファイルハンドルはキャッシュされることがわかっています。これを非常に高く設定し、すぐに上限に達すると、速度が低下します 。少数のテーブルで作業している場合、これは当てはまりません。

9
RolandoMySQLDBA

InnoDBへのデータの一括読み込み専用の document 全体があります。主なポイント:

  1. 自動コミットを無効にして、挿入ステートメントごとに余分なログフラッシュを回避します:SET autocommit=0;...sql import;COMMIT;
  2. 外部チェックと一意チェックを無効にします(すべてのインデックスを完全に無効にすることはできません)。

    SET unique_checks=0;
    SET foreign_key_checks=0;
    
  3. 潜在的に innodb_autoinc_lock_mode を1(デフォルト)ではなく2に設定します。 ここ は、この設定に関するドキュメントです。

3番目の方法は役立つ場合とそうでない場合があるので、そのリンクを読んで、最初にデータをロードする方法を確認することをお勧めします。たとえば、ロードを複数の挿入に分割して同時に実行する場合、値を2に設定することは間違いなく役立ちます。1つの大きな複数行の挿入を実行している場合、(もしあるとしても)多くのことは実行されません。助けて。

この最初の挿入でバイナリログをオンにしているので、自動インクリメント数のギャップを気にする必要はありません(同時挿入を行う場合)。

6
Derek Downey

次の方法を使用して、挿入を高速化できます。

  • 同じクライアントから同時に多くの行を挿入する場合は、INSERTステートメントを複数のVALUESリストと共に使用して、一度に複数の行を挿入します。これは、個別の単一行のINSERTステートメントを使用するよりもかなり高速(場合によっては何倍も高速)です。空でないテーブルにデータを追加する場合は、bulk_insert_buffer_size変数を調整して、データ挿入をさらに高速にすることができます。
  • テキストファイルからテーブルを読み込む場合は、LOAD DATA INFILEを使用します。これは通常、INSERTステートメントを使用するよりも20倍高速です。 参照
  • 列にはデフォルト値があるという事実を利用してください。挿入する値がデフォルトと異なる場合にのみ、値を明示的に挿入します。これにより、MySQLが行う必要のある解析が減り、挿入速度が向上します。
  • InnoDBテーブルに固有のヒントについては、セクション9.5.5「 InnoDBテーブルのバルクデータロード 」を参照してください。
1
user2432735

プランA:「バッチ」INSERT-INSERTステートメントごとに複数の行。ステートメントごとに約1000行を提案します。 autocommit = on、明示的なBEGIN ... COMMITなし

プランB:データの読み込み

一度に挿入する行が多すぎる場合、クラッシュが発生した場合にInnoDBが挿入をロールバックできるようにするには、さらに多くの作業を行う必要があります。このため、セット全体を1つのトランザクションに入れるautocommit = offには同意しません。

行のセット全体のLOAD DATAでも同じ問題が発生する可能性がありますが、非常に高速です。

buffer_pool = 6Gのうち5Gは大きすぎる寸前です。スワッピングがあると、パフォーマンスが低下します。

パーティション設定を行うと、おそらく速度が遅くなります。

SHOW CREATE TABLE-セカンダリキーは深刻なハンディキャップになる可能性があります。

InnoDBを使用していますか?またはXtraDB?

0
Rick James