17

大規模なデータ セットを本番データベースにロードする必要があります。

15 個のファイルをそれぞれアップロードしてテーブルに挿入する必要があります。それぞれ約500 Mbです。

インデックスを作成する必要がある 2 つの ID 列があります。インデックスを配置してファイルをロードすると、アップロードに約 3 時間かかります。インデックスを削除し、ローカル ファイルにデータをロードしてから、インデックスを再度追加すると、操作全体に約 30 分かかります。

問題は、新しくインポートされたデータのインデックス作成中に、データベースの応答性が大幅に低下することです。インデックス作成を「低い優先度」で実行して、他のクエリが 95 ~ 100% の速度で実行され、インデックス作成の種類がバックグラウンドで動作するようにする方法はありますか?

Amazon RDSを使用しているため、別のサーバーにロードしてからテーブル ファイルをコピーするというオプションはありません。

特定のボックスのインデックス作成中に優れたパフォーマンスを得る方法があるかどうかを確認したいので、これに報奨金を追加します。

4

6 に答える 6

4

スロットルする方法は見つかりませんでしたが、問題を軽減する方法を見つけました。解決策は私の問題に固有のものでしたが、他の誰かが役に立つと思った場合に備えて投稿します。

という名前のクラスを書きましたCautiousIndexer

  1. まず、create table ステートメントを格納して、インデックスなしでテーブル構造を再作成しました。読み取りスレーブ データベースの配列を格納し、それらをループ処理して、インデックスのないデータを含むテーブルの名前を に変更しましたprevent_indexing_($name)
  2. 次に、スレーブのみで create table ステートメントを実行しました。これにより、マスターで発生するインデックス作成ステートメントの邪魔にならないようにデータが効果的に移動されました。
  3. 次に、マスターに対してインデックス クエリを実行しました。新しく作成されたテーブルが空だったため、マスターがインデックスを作成している間、読み取りスレーブはパフォーマンスに影響を与えませんでした。
  4. マスターがインデックス作成を終了したとき、私はスレーブの 1 つを生産ローテーションから取り出し、空のテーブルを削除し、テーブル全体を元の場所に移動してから、生産を停止したスレーブのテーブルにインデックスを作成しました。
  5. それが終わったら、本番環境に戻し、残りのスレーブでスレーブのインデックス作成手順を繰り返しました。
  6. すべてのスレーブのインデックスが作成されたら、テーブルを本番環境に置きました。

これでも効率は問題ありませんでしたが、マスター サーバーでのインデックス作成中は書き込みパフォーマンスが許容できないほど遅くなりました。スロットルを使用してインデックスを作成する方法をまだ探しています。

于 2011-05-18T21:30:39.290 に答える
1

これはあなたが探している正確な解決策ではありませんが、この単一のボックスのスレーブとして2番目のmysqldインスタンスを起動SELECTし、必要に応じてクエリをリダイレクトすることができます。クライアントアプリを書き直さずにこれを実現するのに役立つMySQLプロキシがあります。

You can also gather some ideas from FriendFeed usage of MySQL. They store actual indexes in other tables and use them for search. If you store a copy of you data in other table even on other server and run indexes there, you'll be able to access master data ASAP at full speed and get speedier queries later using other server.

It's like if you add indexes on a slave for search-type queries and run only primary key lookups on the master.

于 2011-06-20T07:10:01.050 に答える
1

これに対する適切な解決策は、ローリング更新を実行するスクリプトです。レプリケートしない方法で各スレーブにインデックスを適用します。大まかな図:

for host in $hosts
do
    mysql -h $host -e "STOP SLAVE;\
      SET sql_log_bin=0;\
      FLUSH TABLE t;\
      ALTER TABLE t ADD INDEX a (b,c);\
      SET sql_log_bin=1;\
      START SLAVE;"
done

レプリケーションをオフにすると、ディスク アクティビティの量が減少し、インデックス作成操作の速度が向上します。スレーブにデータベース ラグの要件がある場合は、スレーブを完全にデプールし、0 秒のラグが再開したときにスレーブを再プールするロジックを含めることができます。

于 2011-06-20T23:34:01.090 に答える
0

インポートのインデックス設定を上げてみましたか? これにより、インポートのパフォーマンスが大幅に向上します。sort_buffer_size は任意のテーブル タイプ用で、myisam_sort_buffer_size は MyISAM テーブル用です。innodb_buffer_pool_size は、Innodb の「キー キャッシュ」のようなものです。テーブルの種類に応じて、インポートのためにそれらを増やします。あなたがしようとしているのは、インデックス作成中のファイルの並べ替えを避けることです。

インポート/インデックス作成の時間を 10 ~ 15 分以下に短縮できる場合があります。スロットルではありませんが、影響期間が大幅に短縮されます。

または、MyISAM テーブルを使用している場合、MERGE テーブルはオプションでしょうか? 新しいテーブルを作成し、インポートを実行してから、新しいテーブルを MERGE テーブルに追加します。インポート中のデータベースへの影響はありません。タスクを実行するサーバーは別として。

于 2011-06-23T05:03:52.650 に答える
0

以前に試したことのないアイデアは、インデックスの調整についてもありません。バックアップ テーブルを作成し、前述の方法でそれを更新すると、テーブルの変換/名前変更よりも期間が短くなります。方法を知る必要があるため、私の考えを書くことをお勧めします。

于 2011-06-18T18:10:34.487 に答える
0

挿入中に一意でないインデックスを無効にし、終了後に再度有効にすることができます。キーの無効化/キーの有効化をご覧ください。ただし、一意でないインデックスに対してのみ機能します。

複数値の挿入ステートメントを使用すると、挿入を高速化することもできます (insert into table(...) values(...),(...),(...)...

ちなみに、ロードデータインファイルは、mysqlに大量のデータを挿入する最速の方法のようです。

于 2011-06-19T17:19:11.097 に答える