2017-08-13 8 views
1

ウィキペディアのデータベースをインポートします。 Wikipedia Dumpsなぜステートメントの時間コストの範囲が大きいのですか?

私はいくつかのInnoDBの設定を変更した:

innodb_buffer_pool_size = 4G 
innodb_log_file_size=8G 
innodb_log_buffer_size=512M 
innodb_write_io_threads = 16 
innodb_flush_log_at_trx_commit = 0 
max_allowed_packet=256M 

enter image description here

この絵は、すべて単一のSQL文の時間コストすることを示しています。

次のようなsql文は次のようになります。templatelinksに値を挿入(...)、(...)、(...)、... ... ... 1つのSQL文のサイズはすべて1MBです。

なぜ1300番目から1400番目のSQLには時間がかかりますか?

詳細情報:この期間中

  1. 、このテーブルのサイズは、ほぼ9ギガバイトで、テーブル行40millionです。
  2. SQLステートメントを実行するのにSpring JdbcTemplateを使用します
  3. マイコンピュータのメモリは8Gで、データベースはHDDに格納されています。

コアコード:

JdbcTemplate jdbcTemplate=new JdbcTemplate(mDatasour); 

    while (it.hasNext()){ 
     jdbcTemplate.getDataSource().getConnection().setAutoCommit(false); 
     jdbcTemplate.execute("SET UNIQUE_CHECKS=0; "); 
     jdbcTemplate.execute("SET FOREIGN_KEY_CHECKS=0; "); 
     String line=it.nextLine(); 
     if(line==null||line.length()==0){ 
      continue; 
     } 
     jdbcTemplate.execute(line); 
     jdbcTemplate.execute("commit;"); 

table columns

table index details

+0

テーブルのインデックスを作成していますか? – Muhammad

+1

おそらくあなたのサーバーは何か他のもので忙しくなっていますか?大量の挿入が行われているため、パフォーマンスのボトルネックがディスクの可能性が高いため、サーバー上のバックグラウンドプロセスがディスクを使用し始めた場合(ウイルススキャンなど)、ディスクアームが現在しようとしているため、同時に2つの場所で。 – Andreas

+0

@ムハンマド、私はより多くの情報を追加しました。 –

答えて

1

最適化コード

ループのうち一定のものを引き出し。 COMMITを発行する必要性を回避するために、自動コミットを使用してください。

jdbcTemplate.getDataSource().getConnection().setAutoCommit(true); -- Note 
jdbcTemplate.execute("SET UNIQUE_CHECKS=0; "); 
jdbcTemplate.execute("SET FOREIGN_KEY_CHECKS=0; "); 
while (it.hasNext()){ 
    String line=it.nextLine(); 
    if(line==null||line.length()==0){ 
     continue; 
    } 
    jdbcTemplate.execute(line); 
} 

小さな塊のいずれか小さい方の1000行または1メガバイトのいずれかで

ストップ構築ライン、。それを超えると、あなたはリターンを減らし、元に戻すログを強調します。

は、冗長UNIQUE

ドロップUNIQUE(from, namespace, title)を取り除くある列の同じリストを持っているPRIMARY KEYと冗長です。これは、の間に一意のインデックスをすべてチェックする必要があるため、挿入作業を削減します。 "バッファリングの変更" について

変更バッファリング

読みます。これは本質的に、一意ではないインデックスの遅延書き込み(および最適化)です。膨大な挿入中のある時点で、Changeバッファがいっぱいになり、フラッシュする必要があります。このフラッシングはバックグラウンドで行われるため、スパイクの重大度は説明できません。

テーブルの約1/3がロードされた後に変更バッファがバックログに記録されたと思われ、これが原因で発生した問題です。受信行の

注文を検討する

他のもの...行はどのような順序を書かれていましたか?それらがPK順序で書かれていた場合、各INSERTをPK(およびデータ)(および冗長UNIQUE索引)に実行するために必要なI/Oはごくわずかです。あなたのグラフは、I/Oが最初から長時間低かったことを示しているようです。

しかし、セカンダリインデックス(変更バッファによって処理される)はおそらく非常にランダムです。 (私はfromが何を意味するのかわかりません)。これにより、2つの2次インデックスのインデックスブロックを更新するための多くの "読み込み - 変更 - 書き込み"アクションが発生します。

PK_データではbuffer_poolはそれほど必要ではないが、セカンダリインデックスでは、innodb_change_buffer_max_sizeを調整することを検討してください。デフォルトでは、「変更バッファ用に確保されているbuffer_poolの25%」になっています。ディスクへ

フラッシング

もう一つの問題は:PKへの書き込み+データを超えるまで、ディスクにフラッシュする必要はありません「innodb_max_dirty_pages_pct - BUFFER_POOLの90%デフォルトは」。ここでも、これは初期の低I/Oと一致しています。

これらの2つの設定について学び、周囲で遊んでからブログ記事を書く。あなたはそのような人の専門家になるでしょう。

1

innodb_buffer_pool_size = 4Gでは、innodb_change_buffer_max_sizeに25%を設定した後、有効なプールサイズは3Gです。

あなたのinnodb_io_capacityとinnodb_io_capacity_maxは、今日のHDD容量を利用するために高められる可能性があります。 Microsoftからsqlio.exeをダウンロードすると、HDDの16384(MySQL)データブロックサイズの制限を判断するのに役立ちます。

RAMを追加すると、メモリ内のデータをより長く保持するのに最適です。

関連する問題