2

以前、大規模なデータセットを分析する方法について質問しました ( 13GB のデータを分析するにはどうすればよいですか)。有望な回答の 1 つは、自然キーを使用して MySQL データベースにデータを追加し、それによって INNODB のクラスター化インデックスを利用することでした。

次のようなスキーマでデータベースにデータを追加しました。

TorrentsPerPeer
+----------+------------------+------+-----+---------+-------+
| Field    | Type             | Null | Key | Default | Extra |
+----------+------------------+------+-----+---------+-------+
| ip       | int(10) unsigned | NO   | PRI | NULL    |       |
| infohash | varchar(40)      | NO   | PRI | NULL    |       |
+----------+------------------+------+-----+---------+-------+

2 つのフィールドが一緒になって主キーを形成します。

この表は、トレントをダウンロードするピアの既知のインスタンスを表しています。ピアでいくつの torrent を見つけることができるかについての情報を提供できるようにしたいと思います。torrent の数が表示される頻度のヒストグラムを描画します (たとえば、20 のピアには 2 つの torrent があり、40 のピアには 3 つの torrent があります...)。

次のクエリを作成しました。

SELECT `count`, COUNT(`ip`) 
    FROM (SELECT `ip`, COUNT(`infohash`) AS `count`
              FROM TorrentsPerPeer
              GROUP BY `ip`) AS `counts`
    GROUP BY `count`;

EXPLAINサブセレクトの場合は次のとおりです。

+----+-------------+----------------+-------+---------------+---------+------------+--------+----------+-------------+
| id | select_type | table          | type  | possible_keys | key     | key_length | ref    | rows     | Extra       |
+----+-------------+----------------+-------+---------------+---------+------------+--------+----------+-------------+
| 1  | SIMPLE      | TorrentPerPeer | index | [Null]        | PRIMARY | 126        | [Null] | 79262772 | Using index |
+----+-------------+----------------+-------+---------------+---------+------------+--------+----------+-------------+

EXPLAIN時間がかかりすぎるため、完全なクエリを実行できないようです。このバグは、最初にサブクエリを実行しているためであることを示唆しています。

このクエリは現在実行中です (1 時間経過しています)。は、使用可能な CPU の 5% しか使用していない一方で、着実に増加してtopいると報告しています。ここでの私の仮定は、サーバーがクエリを完了するために使用する RAM に一時テーブルを構築していることです。mysqldRSIZE

私の質問は次のとおりです。このクエリのパフォーマンスを改善するにはどうすればよいですか? どういうわけかクエリを変更する必要がありますか? ファイルのサーバー設定を変更しmy.cnfて INNODB バッファ プール サイズを増やしましたが、他の値を変更する必要がありますか?

それが重要な場合、テーブルの深さは 79'262'772 行で、最大 8 GB のディスク領域を占有します。これが簡単なクエリになるとは思っていません。おそらく「忍耐」が唯一の合理的な答えです。

編集クエリが終了し、105分かかったと付け加えるだけです。仕方がないので、少しでも改善されることを祈るばかりです。

4

1 に答える 1

1

私の推測では、unsigned int と varchar 40 (特に varchar!) を使用すると、巨大な主キーが作成され、インデックス ファイルが大きくなりすぎて、Innodb_buffer_pool 用の RAM に収まりません。これにより、InnoDB は検索時にインデックス ページを交換するためにディスクに依存する必要があり、これは大量のディスク シークであり、多くの CPU 作業ではありません。

同様の問題に対して私が行ったことの 1 つは、真に自然なキーと代理キーの間の何かを使用することです。実際に一意である 2 つのフィールド (そのうちの 1 つは varchar でもあります) を取得し、アプリケーション層で固定幅の MD5 ハッシュを作成し、それをキーとして使用します。はい、それはアプリの作業が増えることを意味しますが、任意の長さのフィールドを使用しなくなったため、インデックス ファイルがはるかに小さくなります。

または、大量のRAMを備えたサーバーを使用して、インデックスがメモリに収まるかどうかを確認することもできますが、私は常に最後の手段として「ハードウェアを投げる」ことを好みます:)

于 2012-08-16T15:54:37.380 に答える