3

私はこの簡単なクエリを持っています:

INSERT IGNORE INTO beststat (bestid,period,rawView) VALUES ( 4510724 , 201205 , 1 ) 

テーブルの上:

CREATE TABLE `beststat` (
 `bestid` int(11) unsigned NOT NULL,
 `period` mediumint(8) unsigned NOT NULL,
 `view` mediumint(8) unsigned NOT NULL DEFAULT '0',
 `rawView` mediumint(8) unsigned NOT NULL DEFAULT '0',
 PRIMARY KEY (`bestid`,`period`),
) ENGINE=InnoDB AUTO_INCREMENT=2020577 DEFAULT CHARSET=utf8

そして、完了するまでに1秒かかります。


補足:実際には、常に 1 秒かかるわけではありません。0.05秒で終わることもあります。しかし、多くの場合、1秒かかります


このテーブル (beststat) には現在~500'000レコードがあり、そのサイズは40MBです。私は4GB の RAMinnodb buffer pool size= 104,857,600を持っています: Mysql : 5.1.49-3

これは私のデータベースで唯一の InnoDB テーブルです (他は MyISAM です)

ANALYZE TABLE beststatショー: OK

InnoDB の設定に問題があるのでしょうか。

4

2 に答える 2

2

顧客向けの評価プロジェクトの一環として、約 3 年前にいくつかのシミュレーションを実行しました。データが常に追加されているテーブルを検索できるようにする必要があり、最新の状態を 1 分以内に維持したいと考えていました。

InnoDB は最初ははるかに優れた結果を示していましたが、すべてのインデックス (プライマリを含む) を削除するまで、急速に悪化しました (100 万レコードのかなり前)。その時点で、InnoDB は挿入/更新の実行時に MyISAM よりも優れています。(私のラップトップでのみテストを実行しているあなたよりもはるかに悪いハードウェアを持っています。)

結論: インデックスがあり、特に一意の場合、挿入は常に影響を受けます。

次の最適化をお勧めします。

  1. beststat テーブルからすべてのインデックスを削除し、単純なダンプとして使用します。
  2. これらの一意のインデックスが本当に必要な場合は、プログラム可能な解決策を検討してください (常に最大の bestid を記憶し、新しいレコードがその数値を超えていることを主張し、すぐにこの数値を増やすなど)。 (しかし、本当に多くの一意のフィールドが必要ですか?そして、それらはすべてインデックスのように聞こえます。)
  3. バックグラウンド スレッドで、新しいレコードを InnoDB から別のテーブル (MyISAM の場合もある) に移動し、そこでインデックスを作成します。
  4. インデックスを一時的に削除し、一括更新後にテーブルのインデックスを再作成することを検討してください。クエリが中断されないように、2 つのテーブルを切り替える可能性があります。

これらは理論的な解決策であることは認めますが、あなたの質問を踏まえて私が言える最善の方法です。

ああ、テーブルが数百万に拡大する予定がある場合は、NoSQL ソリューションを検討してください。

于 2012-05-12T10:23:23.947 に答える
1

したがって、テーブルには 2 つの一意のインデックスがあります。主キーは自動番号です。これは実際にはデータの一部ではないため、データに追加すると、人工的な主キーと呼ばれるものになります。これで、bestid と period に関する一意のインデックスが作成されました。bestid と period が一意であると想定される場合、それは主キーの適切な候補になります。

Innodb は、テーブルをツリーまたはヒープとして格納します。innodb テーブルで主キーを定義しない場合、ディスク上のツリーとして定義される主キーを定義するとヒープになります。したがって、あなたの場合、ツリーは自動番号キーに基づいてディスクに保存されます。したがって、2 番目のインデックスを作成すると、ディスク上に 2 番目のツリーが実際に作成され、インデックスに bestid と period の値が含まれます。インデックスには、テーブル内の他の列は含まれず、bestid、期間、および主キー値のみが含まれます。

わかりましたので、データを挿入します。最初に行うことは、一意のインデックスが常に一意であることを確認することです。したがって、インデックスを読み取って、重複する値を挿入しようとしているかどうかを確認します。これがスローダウンの出番です。テスト書き込みデータに合格した場合は、最初に一意性を確認する必要があります。次に、bestid、期間、および主キーの値を一意のインデックスに挿入する必要もあります。したがって、合計操作は、値 1 行をテーブルに挿入 1 ベスト ID とピリオドをインデックスに挿入するための 1 つの読み取りインデックスになります。合計3回の手術。自動付番を削除し、一意のインデックスのみを主キーとして使用した場合、テーブルに一意に挿入するとテーブルが読み取られます。この場合、次の数の操作が必要になります。 1 テーブルを読み取り、値をチェックします。 1 テーブルに挿入します。これは 2 つの操作と 3 つの操作です。

私は Android から入力していて、オートコレクトが innodb を inborn に変更し続けているので、これが明確であることを願っています。私がコンピューターにいたらいいのに。

于 2012-05-12T10:55:17.163 に答える