Use the left/right arrow keys to navigate.

私は如何にして3億件のデータを2日でRDBに突っ込んだか

どういう状況か

  • 大学で検索に関する研究をしてました
  • 文書中から名詞の共起を取り出す、という作業がありました
  • 共起とは文中で同時に二つの単語が用いられている状態を指します
  • 例えば「居酒屋ビールを頼む」という文章では「居酒屋」と「ビール」が共起しています
  • こういった情報を大量に収集する必要がありました

具体的にいうと

  • 10万件 の HTML から
  • 100万語 の名詞を収集して
  • 3億件 の共起の組み合わせとその回数を

データベースに突っ込む作業

ちなみに環境は

  • OS: CentOS
  • DB: MySQL
  • 言語: Python

愚直な方法だといつまでたっても終わらない

テーブルを一つ用意して延々 INSERT するような方法だと

いつまでたっても終りが見えません

Try And Error で発見した高速化するための方法

紹介していきたいと思います

UPDATE を使わない

  • UPDATE は低速です
  • データの集計をする場合は unix コマンドの sort を使います
  • sort の merge オプションを使うとソート済みの複数ファイルを統合できます

% sort --merge hoge1.txt hoge2.txt -o hoge.txt

マルチプル INSERT を使う

  • 複数行まとめて INSERT します
  • やりすぎると速度が落ちます
  • 私が試した環境では 1000件 程度がもっとも高速でした

複数テーブルにデータを分ける

  • レコード数が増えると、INSERT の速度が低下します
    • 1000万件くらいから速度低下の傾向が見られました
  • 新しいテーブルを用意してそこへ INSERT した方が良いです
  • そのままだと再利用しづらい

MERGE TABLE 機能を使う

  • 複数テーブルを仮想的に一つのテーブルとして扱える
  • データが増えるたびに随時テーブルを追加すればよい
  • INSERT 速度を維持 & 再利用性を確保

まとめ

MySQL へ大量のデータを高速に INSERT するには

  • UPDATE を使わない
  • マルチプル INSERT を使う
  • 複数テーブルにデータを分ける
  • MERGE TABLE 機能を使う

万が一同様の状況に陥った場合はお試しください