2

我之前问过一个关于如何分析大型数据集的问题(如何分析 13GB 的数据)。一个有希望的回应是使用自然键将数据添加到 MySQL 数据库中,从而利用 INNODB 的聚集索引。

我已将数据添加到数据库中,其架构如下所示:

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

这两个字段共同构成主键。

该表表示已知的对等点下载种子的实例。我希望能够提供有关在同行中可以找到多少种子的信息。我将绘制我看到种子数量的频率的直方图(例如,20 个对等点有 2 个种子,40 个对等点有 3 个,...)。

我写了以下查询:

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为完整的查询做一个,因为它需要的时间太长了。这个错误表明这是因为它首先运行子查询。

此查询当前正在运行(并且已经运行了一个小时)。top报告说mysqld它只使用了大约 5% 的可用 CPU,而它却在RSIZE稳步增长。我的假设是服务器正在 RAM 中构建用于完成查询的临时表。

我的问题是;如何提高此查询的性能?我应该以某种方式更改查询吗?我一直在更改my.cnf文件中的服务器设置以增加 INNODB 缓冲池大小,我应该更改任何其他值吗?

如果重要的话,该表的深度为 79'262'772 行,并占用约 8GB 的​​磁盘空间。我不希望这是一个简单的查询,也许“耐心”是唯一合理的答案。

编辑只是补充一下查询已经完成并且花了 105 分钟。这不是无法忍受的,我只是希望有一些改进。

4

1 回答 1

1

我的预感是,使用 unsigned int 和 varchar 40(尤其是 varchar!)你现在有一个巨大的主键,它使你的索引文件太大而无法容纳你为 Innodb_buffer_pool 拥有的任何 RAM。这将使 InnoDB 在搜索时必须依赖磁盘来交换索引页,这需要大量的磁盘搜索,而不是大量的 CPU 工作。

我为类似的问题做的一件事是在真正的自然键和代理键之间使用一些东西。我们将采用实际唯一的 2 个字段(其中一个也是 varchar),并在应用程序层中制作一个固定宽度的 MD5 哈希并使用 THAT 作为键。是的,这意味着应用程序需要做更多的工作,但它会生成更小的索引文件,因为您不再使用任意长度的字段。

或者,您可以只使用具有大量 RAM 的服务器,看看这是否使索引适合内存,但我总是喜欢将“扔硬件”作为最后的手段:)

于 2012-08-16T15:54:37.380 回答