1

このテーブルには 700 万行を超える行がありLOAD DATA LOCAL INFILE、一度に 50 万行程度のデータを追加しています。最初の数回は高速でしたが、おそらくインデックス作成のオーバーヘッドが原因で、この追加に時間がかかっています。

CREATE TABLE `orthograph_ests` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `digest` char(32) NOT NULL,
  `taxid` int(10) unsigned NOT NULL,
  `date` int(10) unsigned DEFAULT NULL,
  `header` varchar(255) NOT NULL,
  `sequence` mediumblob,
  PRIMARY KEY (`id`),
  UNIQUE KEY `digest` (`digest`),
  KEY `taxid` (`taxid`),
  KEY `header` (`header`)
) ENGINE=InnoDB AUTO_INCREMENT=12134266 DEFAULT CHARSET=latin1

既存のデータベースで実行するアプリケーションを開発しています。サーバー変数を強制的に変更しない限り、サーバー変数を制御できない可能性が高いため (そうしないことを好みます)、これらのような提案は使用が制限されていると思います。

このテーブルのキーを最小化すると役立つことを読みました。ただし、後のクエリにはこれらのキーが必要です。ドロップして再作成すると、非常に時間がかかると思いますが、これはテストしていません。UNIQUEまた、特に制約により挿入が遅くなることも読みました。この列は一意である必要digestがあるSHA256 ダイジェストを取得しますが、衝突がないことを確認することはできません (可能性はほとんどありませんが、可能性はあります)。

ここで提案されているように、パーティショニングは役立ちますか? digest列のキーの長さを制限するなどして、索引付けを改善できますか? 取引中対応のMyISAMに変更したDISABLE KEYSほうがいいですか?LOAD DATAパフォーマンスを向上させるために他に何ができますか?

編集:

大規模な挿入の後、このテーブルはSELECTs のみに使用され、書き込みは行われません。この大規模な読み込みは、ほとんどが 1 回限りの操作ですが、完了する前に (0.5M 行ごとに) 約 1,000 データセットをアップロードする必要があります。

ダイジェストを使用して行を検索するため、その列にインデックスを付けました。競合が発生した場合、その個々の行はアップロードされません。

ファイル システムの変更をユーザーに簡単に課すことはできないため、sequenceブロブを外部ファイル システムに配置することはおそらく実行可能なオプションではありません。

4

2 に答える 2

2

これは実際にロードしている大量のデータであり、特に汎用の共有サーバー ハードウェアでは、数十時間かかることが予想されます。この仕事を首の大きな痛み以外のものにする魔法はほとんどありません (Google などで働いている場合を除く)。ですから、勇気を持ってください。

参考表です。つまり、すぐに MyISAM に切り替えて、このテーブルにとどまる必要があります。InnoDB のトランザクション整合性機能は必要ありませんが、ロード中にインデックス作成を無効にし、後で再度有効にするために MyISAM が必要です。インデックス作成の再有効化には時間がかかるため、それに備えてください。

SHA-256 よりも短いハッシュの使用を検討する必要があります。SHA-1 (160 ビット) が適しています。信じられないかもしれませんが、MD-5 (128 ビット) も役立つかもしれません。MD-5 はクラックされているため、安全なコンテンツ認証には適していません。しかし、それでも有用なハッシュです。短いハッシュは、あなたの観点からはより良いハッシュです。

MyISAM スタイルのインデックス作成を無効にできれば、ダイジェスト キーが一意であるかどうかはおそらく問題になりません。ただし、時間を節約するために、一意でないことを許可することを検討することもできます。

データとサーバー ハードウェアについて詳しく知らずに、パーティショニングについて提案することは困難です。しかし、これが参照データベースであることを考えると、数週間弾丸を噛んでロードするのが賢明なようです.

サーバーのディスク容量が十分にある場合は、半メガ行の各チャンクをそれぞれのテーブルにロードしてから、大きなテーブルに挿入することを検討してください。これは、いつかすべてをリロードしなければならない可能性に対処するための良い方法であることが証明されるかもしれません.

共有サーバー ハードウェアでは、メガローの半分よりも小さいチャンクを使用することが理にかなっている場合があります。

別の id / ダイジェスト テーブルを作成することを検討してください。その後、ダイジェストなしでデータをロードして、すばやく完了することができます。次に、ダイジェストが完了するまで、それぞれ数千行のバッチでダイジェストを作成するストアド プロシージャまたはクライアントを自分で作成できます。これは、消化されているものがデータセットにある場合にのみ機能します。

于 2013-01-07T16:55:28.087 に答える
1

基本的に、データの読み込みが遅くなる理由は 2 つあります。

  1. データ自体を挿入する際の書き込みパフォーマンス。
  2. 新しいデータを追加しながら既存のページを変更するために、既存のデータをロードするために既存のデータを読み取る読み取りパフォーマンス。

書き込みパフォーマンスの問題は、主に耐久性を下げ、ログを減らすことで対処できます。これは、次の設定など、多くの提案が表示される内容です: innodb_flush_log_at_trx_commit=0innodb_doublewrite=0innodb_support_xa=0. を設定するなどして、書き込まれるデータのを減らすことも役立ちますlog-bin=0。ただし、顧客が既存の本番システムでこれらの耐久性関連の設定を変更することを期待することも、実際には受け入れられません。それらの変更は、既存のシステムに定期的にデータを追加するよりも、専用システムでのワンショット バルク ロードに適しています。

一括読み込みINSERT(多数の行を含む) を行うか、1 つのトランザクションでより多くのデータを書き込むことでLOAD DATA INFILE書き込みスループットの要件を減らして、トランザクション ログへの同期の回数を減らします。ただし、書き込みスループットを削減したり、書き込みパフォーマンスを向上させたりしても、ある程度の効果しかありません。

PRIMARY KEYインデックス構造にデータを挿入するときに不要なページ分割の量を減らすために、ロードする前にデータをソートすることも一般的に役立ちます。ただし、複数の二次キーがある場合は、使用が制限されPRIMARY KEYます。並べ替えは、少なくとも 1 つの二次キーによってデータが並べ替えられていないことを必然的に意味するためです。

読み取りパフォーマンスの問題はおそらくより興味深いものであり、特にセカンダリ キーが存在する場合に、既存のテーブルに新しいデータをロードする際の実際のパフォーマンスの問題であることがよくあります。最善の方法は、既存のすべてのデータがメモリに収まる (innodb_buffer_pool_size十分な大きさである) ことであり、ロード中にキャッシュのデータをページングしたりページアウトしたりする必要はありません。数百万行しか話していないことを考えると、これは実現可能かもしれません。

于 2013-01-08T16:30:31.567 に答える