2

次の表を検討してください。

CREATE TABLE `event` (
  `uid` bigint(13) NOT NULL,
  `time` bigint(14) NOT NULL,
  `type` smallint(5) NOT NULL,
  `msg` varchar(2048) DEFAULT NULL,
  KEY `uid` (`uid`),
  KEY `time` (`time`),
  KEY `time_type_uid` (`time`,`type`,`uid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

私が基本的にしていること:

  • INSERT1 日あたり最大 100 万行、現在のサイズは約 1 億エントリです
  • DELETE100 日以上前のすべての行:
    • ステートメント #1:DELETE FROM event WHERE time < unix_timestamp()-100*86400;
    • ステートメント #2:DELETE FROM event WHERE time < unix_timestamp()-100*86400 LIMIT 1000;
  • ユーザーはSELECTすべてのイベントを UID で行います。合計で 1 日に約 500 件のクエリが実行されるため、それほど多くはありません。
    • ステートメント #1:SELECT * FROM event WHERE uid=4711 AND type IN (23,1002,12,1);
    • ステートメント #2:SELECT * FROM event WHERE uid=4711 AND type IN (23,1002,12,1) AND time BETWEEN 1381051061 AND 1381051861;

特にジョブがテーブルのs/ s をDELETEブロックするため、このテーブルの処理は非常に遅くなりました。上記 (ステートメント #1) で説明したように、毎日の一括処理を試みましたが、テーブルをブロックしないと機能しなくなりました。現在、30 秒ごとに削除していますが (ステートメント #2)、これは 10 秒間ブロックされます。INSERTSELECTDELETE

負荷を増やす予定ですINSERTが、最初のテストではスレッドが「システム ブロック」状態でハングします。これは I/O が原因であると推測されます。サーバー設定は、mysqltuner.pl で提案されているように最適化されています。ハードウェア システムには確実に I/O の問題があり、「現状のまま」ですが、残念ながらいくつかの理由で変更できません。ルートアクセスすらありません。

パーティショニングはソリューションでもありますか? MyISAM は使用するのに最適なエンジンですか? ハードウェアを改善する前に、可能な限り最適化する必要があります。

4

2 に答える 2

0

読み取り可能なスナップショットを取得するには、スナップショット分離で InnoDB を使用するだけです。そうすれば、大量の削除ジョブによってリーダーがブロックされることはありません。このかなり標準的な状況では、パーティショニングに行くべきではないと思います。パーティショニングは大きなハンマーであり、侵襲的です。たぶん、いくつかの簡単な対策で十分です。

于 2013-10-05T17:39:07.853 に答える
0

パーティショニングの問題 (うまく機能しますが、システム管理者の毛玉になる可能性があります) に入る前に、いくつかのことを試してください。

DELETE クリーンアウト オペレーションを 1 日に複数回 (1 時間に複数回) 実行するため、実行するたびに 100 万行を処理する必要がありません。

実行してみてください

    DELETE FROM event
          WHERE TIME < < unix_timestamp()-100*86400
         LIMIT 10000

何度も何度も。これにより、各 DELETE 操作でテーブルがロックされる時間が短縮され、他の操作のためにテーブルが解放されます。

適切な複合インデックス (時間、タイプ、uid) があるかどうかを調べます。あなたが私たちに示したクエリはそのインデックスを活用していません。また、挿入時にインデックスに時間がかかります。そのインデックスを単純に削除してみてください。言及したクエリの (uid,type) にインデックスが必要な場合があります。

の使用を取り除きますSELECT *。代わりに、アプリケーションが必要とする列のみを取得してください。MySQL は、必要なデータ項目を正確に認識している場合、驚くべき最適化を行うことができます。

毎日または毎週のダウンタイムを許容できますか? その場合は、

 OPTIMIZE NO_WRITE_TO_BINLOG TABLE  event

ときどき、テーブルとインデックスの構造を整理してください。

于 2013-10-05T17:48:45.117 に答える