16

MySQLドキュメントは言う:

B ツリー インデックスを想定すると、テーブルのサイズによってインデックスの挿入がログ N だけ遅くなります。

これは、新しい行を挿入するたびに、挿入速度がlog Nの係数で遅くなることを意味します.Nは行数だと思いますか?すべての行を 1 つのクエリに挿入しても? すなわち:

INSERT INTO mytable VALUES (1,1,1), (2,2,2),  (3,3,3), .... ,(n,n,n)

n は ~70,000 です

現在、次の構造のテーブルに約 147 万行あります。

CREATE TABLE mytable (
   `id` INT,
   `value` MEDIUMINT(5),
   `date` DATE,
   PRIMARY_KEY(`id`,`date`)
) ENGINE = InnoDB

上記の方法でトランザクションに挿入すると、コミットにかかる時間は約 275 秒です。新しいデータが毎日追加され、挿入時間が遅くなり続けるため、これを最適化するにはどうすればよいですか。

また、クエリ以外に役立つものはありますか? おそらくいくつかの構成設定?

考えられる方法 1 - インデックスの削除

挿入の直前にインデックスを削除すると、挿入速度が向上する可能性があることを読みました。挿入後、再度インデックスを追加します。しかし、ここでは唯一のインデックスは主キーであり、私の意見では、それを削除してもあまり役に立ちません。また、主キーが削除されている間は、すべての選択クエリが非常に遅くなります。

私は他の可能な方法を知りません。

編集:〜147万行のテーブルに〜60,000行を挿入するいくつかのテストを次に示します。

上記の単純なクエリを使用した場合: 146 秒

MySQL の LOAD DATA infile の使用: 145 秒

MySQL の LOAD DATA infile を使用し、David Jashi の回答で提案されているように csv ファイルを分割します。それぞれ 1000 行の 60 ファイルで 136 秒、それぞれ 10,000 行の 6 ファイルで 136 秒

主キーの削除と再追加:キーの削除には 11 秒、データの挿入には 0.8 秒かかりましたが、主キーの再追加には 153 秒、合計で 165 秒かかりました

4

5 に答える 5

24

高速挿入が必要な場合、最初に必要なのは適切なハードウェアです。これは、十分な量の RAM、機械式ドライブの代わりに SSD、およびかなり強力な CPU を前提としています。

InnoDB を使用しているため、デフォルトの構成は低速で古いマシン用に設計されているため、最適化する必要があります。

InnoDB の構成に関する優れた資料を次に示します。

その後、1 つのことを知っておく必要があります。それは、データベースが内部でどのように機能するか、ハード ドライブがどのように機能するかなどです。次の説明では、メカニズムを単純化します。

トランザクションとは、MySQL がハード ドライブがデータを書き込んだことを確認するのを待っていることです。そのため、機械式ドライブではトランザクションが遅くなり、1 秒あたり 200 ~ 400 回の入出力操作を行うことができます。つまり、機械式ドライブで InnoDB を使用して、1 秒あたり 200 回の挿入クエリを取得できるということです。当然、これは単純化された説明であり、何が起こっているかを概説するためのものであり、 transaction の背後にある完全なメカニズムではありません

クエリ、特にテーブルのサイズに対応するクエリはバイト単位で比較的小さいため、単一のクエリで貴重な IOPS を効果的に浪費しています。

単一のトランザクションで複数のクエリ (100 または 200 以上、正確な数はありません。テストする必要があります) をラップしてコミットすると、1 秒あたりの書き込み数が即座に増加します。

Percona の連中は、比較的安価なハードウェアで 1 秒あたり 15,000 の挿入を達成しています。1 秒間に 5k 挿入しても問題ありません。あなたのようなテーブルは小さく、同様のテーブル(3列以上)でテストを行い、240GB SSD(1ドライブ、RAIDなし、テスト目的で使用されます)。

TL;DR: - 上記のリンクをたどり、サーバーを構成し、SSD を取得し、1 つのトランザクションで複数の挿入をラップして利益を上げます。また、インデックス作成をオフにしてからオンにしないでください。常に適用できるわけではありません。ある時点で、それらを構築するために処理と IO 時間を費やすことになるからです。

于 2013-06-07T15:43:19.543 に答える
6

とにかく、インデックスを削除すると確実に役立ちます。の使用も検討してLOAD DATAください。ここでいくつかの比較とベンチマークを見つけることができます

また、PRIMARY KEY を構築するときは、テーブルの最初にあるフィールドを順番に使用します。つまり、構造内の 2 番目と 3 番目のフィールドの場所を入れ替えます。

于 2013-06-07T06:52:48.600 に答える
3

100 万行の一括挿入を行う場合は、インデックスを削除し、挿入を行い、インデックスを再構築する方がおそらく高速です。ただし、単一行の挿入に時間がかかりすぎるという問題がある場合は、他の問題 (メモリ不足など) があり、インデックスを削除してもあまり役に立ちません。

于 2013-06-07T06:59:35.040 に答える