多くの詳細なテストを行うことをお勧めしますが、私のテストでは、以前に投稿したテーブル定義を使用して INSERT と SELECT の両方で非常に良い結果を達成しています。誰でも簡単に繰り返して、より良い結果が得られるかどうかを確認できるように、テストの詳細を詳しく説明します。テストの前にデータをバックアップしてください。
これらは単なるテストであり、実際のケースを反映または改善しない可能性があると言わざるを得ませんが、学習の良い方法であり、おそらく有用な情報と結果を見つける方法です.
ここで見たアドバイスは非常に優れており、TEXT の代わりに事前定義された型 VARCHAR とサイズを使用することで、速度が大幅に向上することに気付くでしょう。ただし、速度を上げることはできますが、データの整合性の理由から MyISAM を使用せず、InnoDB を使用することをお勧めします。
テスト:
1. テーブルを設定し、2 億のデータを挿入します。
CREATE TABLE `entity_versionable` (
`version` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`fk_entity` INT(10) UNSIGNED NOT NULL,
`str1` VARCHAR(255) DEFAULT NULL,
`str2` VARCHAR(255) DEFAULT NULL,
`bool1` TINYINT(1) DEFAULT NULL,
`double1` DOUBLE DEFAULT NULL,
`date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`version`,`fk_entity`)
) ENGINE=INNODB AUTO_INCREMENT=230297534 DEFAULT CHARSET=latin1
約 35 分で +2 億行をテーブルに挿入するには、petermがテーブルを埋める最良の方法の 1 つに答えた私の他の質問を確認してください。それは完全に機能します。
ランダム データのない 2 億行を挿入するために、次のクエリを 2 回実行します (ランダム データを挿入するたびにデータを変更します)。
INSERT INTO `entity_versionable` (fk_entity, str1, str2, bool1, double1, DATE)
SELECT 1, 'a1', 238, 2, 524627, '2013-06-16 14:42:25'
FROM
(
SELECT a.N + b.N * 10 + c.N * 100 + d.N * 1000 + e.N * 10000 + f.N * 100000 + g.N * 1000000 + h.N * 10000000 + 1 N FROM
(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a
,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b
,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) c
,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) d
,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) e
,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) f
,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) g
,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) h
) t;
* 2 億行の実際のランダム データを含む元のテーブルが既にあるため、テーブル データとスキーマをエクスポートし、同じスキーマを持つ新しい Testing テーブルにインポートするだけで、おそらくテーブルに入力する必要はありません。そうすれば、実際のデータを使用して新しいテーブルでテストを行うことができ、得られる改善は元のテーブルでも機能します。
2. パフォーマンスのために新しい Test テーブルを変更します(または、上記の手順 1 の例を使用して、より良い結果を取得します)。新しい Test テーブルをセットアップしてランダム データを入力したら、上記のアドバイスを確認し、テーブルを ALTER して高速化する必要があります。
- TEXT を VARCHAR(255) に変更します。
- 2 つまたは 3 つの列を持つ適切な主キーの一意のインデックスを選択して作成します。最初のテストで、バージョンの自動インクリメントと fk_entity を使用してテストします。
- 必要に応じてテーブルを分割し、速度が向上するかどうかを確認します。データ型とmysql構成を変更して実際のパフォーマンスの向上を確認するために、最初のテストではパーティション分割しないことをお勧めします. 分割と改善のヒントについては、次のリンクを確認してください。
- テーブルを最適化して修復します。インデックスが再度作成され、検索が大幅に高速化されます。
テーブルを最適化しますtest
。entity_versionable
;
テーブルを修復しtest
ます。entity_versionable
;
*最適化を実行するスクリプトを作成し、インデックスを最新の状態に維持し、毎晩起動します。
3.次のスレッドを注意深く読んで、MySQL とハードウェアの構成を改善してください。それらは読む価値があり、より良い結果が得られると確信しています。
- 多少の費用をかけて、データベースのハード ディスク構成を簡単に改善します
。可能であれば、メインの MySQL データベースに SSD を使用し、
バックアップ用にスタンドアロンの機械式ハード ディスクを使用します。INSERTの速度を向上させるために、MySQL ログを別の 3 番目のハードディスクに保存するように設定します
。(数週間後に機械式ハードディスクの最適化を忘れずに)。
- パフォーマンス リンク:一般 & マルチコア、構成、
IO の最適化、Debiancores、最適な構成、
構成48 GB RAM ..
- SQL クエリのプロファイリング: クエリのプロファイリング方法、クエリのボトルネックの可能性を確認する
- MySQL は非常にメモリを集中的に使用するため、可能であれば低レイテンシの CL7 DDR3 メモリを使用してください。トピックから少し外れますが、システム データが重要な場合は、ECC メモリを探すことができますが、高価です。
4. 最後に、テスト テーブルで INSERT と SEARCH をテストします。上記のテーブル スキーマを使用して 2 億以上のランダム データをテストしたところ、新しい行を挿入するのに 0.001 秒、1 億行を検索して選択するのに約 2 分かかりました。ただし、それは単なるテストであり、良い結果のようです:)
5. 私のシステム構成:
- データベース: MySQL 5.6.10 InnoDB データベース (テスト)。
- プロセッサー: AMD Phenom II 1090T X6 コア、各コア 3910Mhz。
- RAM: 16GB DDR3 1600Mhz CL8。
- HD: SSD に Windows 7 64 ビット SP1、SSD に mySQL をインストール、機械式ハード ディスクにログを書き込みます。MySQL は 1 つの SQL に対して 1 つのコアしか使用しない
ため、おそらく最新の Intel i5 または i7 の 1 つを 4500Mhz+ に簡単にオーバークロックすると、より良い結果が得られるはずです。コア速度が高いほど、実行速度が速くなります。
6. MySQL の詳細:
O'Reilly High Performance MySQL
MySQL SQL ステートメントの最適化
7. 別のデータベースの使用:
MongoDB またはRedisはこのケースに最適で、おそらく MySQL よりもはるかに高速です。どちらも習得が非常に簡単で、どちらにも利点があります。
- MongoDB: MongoDB ログ ファイルの増大
レディス
私は間違いなくRedisを選びます。ログを Redis に保存する方法を学べば、非常に高速にログを管理するための最良の方法になります
。
Redis は C でコンパイルされ、メモリに格納されます。情報をディスクに自動的に保存する (永続化する) いくつかの異なる方法があります。おそらく心配する必要はありません。(災害シナリオの場合、約 1 秒のログが失われます)。
Redis は、テラバイト単位のデータを管理する多くのサイトで使用されています。その非常識な量の情報を処理する方法はたくさんあります。つまり、Redis が安全であることを意味します (ここでは、stackoverflow、blizzard、twitter、youporn で使用されています..)
ログは非常に大きくなるため、ハードディスクにアクセスせずに高速化するには、メモリに収まる必要があります。異なる日付の異なるログを保存し、それらの一部のみをメモリに設定できます。メモリの上限に達した場合でも、エラーは発生せず、すべてが完全に機能しますが、詳細についてはRedis FAQを確認してください。
この目的では、Redis が MySQL よりもはるかに高速になると確信しています。lists
データの操作方法と更新方法、および
sets
データのクエリ/検索方法について学習する必要があります。非常に高度なクエリ検索が必要な場合は、MongoDB を使用する必要がありますが、この場合、単純な日付検索は Redis に最適です。
Instagram ブログの素敵な Redis 記事。