2

我有几百万行的下表:

CREATE TABLE `points` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `DateNumber` int(10) unsigned DEFAULT NULL,
  `Count` int(10) unsigned DEFAULT NULL,
  `FPTKeyId` int(10) unsigned DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id_UNIQUE` (`id`),
  KEY `index3` (`FPTKeyId`,`DateNumber`) USING HASH
) ENGINE=InnoDB AUTO_INCREMENT=16755134 DEFAULT CHARSET=utf8$$

如您所见,我已经创建了索引。我不知道我做对了可能不是。问题是查询执行速度非常慢。

让我们来一个简单的查询

SELECT fptkeyid, count FROM points group by fptkeyid

我无法获得结果,因为查询因超时(10 分钟)而中止。我做错了什么?

4

4 回答 4

3

当心 MySQL 的愚蠢行为:GROUP BYing 隐式执行ORDER BY.

为防止这种情况,请显式添加ORDER BY NULL,以防止不必要的排序。

http://dev.mysql.com/doc/refman/5.0/en/select.html说:

如果您使用 GROUP BY,则输出行将根据 GROUP BY 列进行排序,就好像您对相同的列有一个 ORDER BY。为了避免 GROUP BY 产生的排序开销,添加 ORDER BY NULL:

SELECT a, COUNT(b) FROM test_table GROUP BY a ORDER BY NULL;

+

http://dev.mysql.com/doc/refman/5.6/en/group-by-optimization.html说:

为 GROUP BY 使用索引的最重要的先决条件是所有 GROUP BY 列都引用来自同一索引的属性,并且索引按顺序存储其键(例如,这是 BTREE索引而不是HASH索引)。

于 2012-06-30T17:16:38.130 回答
1

我个人会从你的AUTO_INCREMENT价值开始。您已将其设置为每增加16,755,134一条新记录。您的字段值设置为INT UNSIGNED这意味着值的范围是0 to 4,294,967,295(或近 43 亿)。这意味着您将只有256在字段超出数据类型限制之前的PRIMARY KEY INDEX,从而损害.

您可以将数据类型更改为,并且您将拥有一个(或略多于 18.4 quintillion)BIGINT UNSIGNED的值范围,这将允许您拥有最多(或略多于 1.1 万亿)具有此值的唯一值。0 to 18,446,744,073,709,551,6151,100,960,700,983AUTO_INCREMENT

我首先会问您是否真的需要将AUTO_INCREMENT值设置为如此大的数字,如果不需要,那么我建议将其更改为 1(或至少一些较低的数字),因为将字段值存储为INTvsBIGINT将在其中节省大量磁盘空间像这样的更大的桌子。无论哪种方式,你都应该得到一个更稳定的PRIMARY KEY INDEX,这应该有助于改进查询。

于 2012-06-30T18:18:52.563 回答
1

您的查询没有意义:

SELECT fptkeyid, count FROM points group by fptkeyid

您按 fptkeyid 分组,因此 count 在这里没有用。应该有一个聚合函数。不是计数字段。接下来,该计数也是一个 MySQL 函数,这使得对字段使用相同的名称不是很有用/不明智。

你不需要类似的东西:

SELECT fptkeyid, SUM(`count`) FROM points group by fptkeyid

如果不是,请解释您期望从查询中得到什么结果。

用测试数据创建了一个数据库,一百万条记录,看看我是否能找到与你的问题相同的东西。这是解释告诉我的:

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  points  index   NULL    index3  10  NULL    433756  

在 SUM 查询中:

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  points  index   NULL    index3  10  NULL    491781   

这两个查询都是在一秒钟内在笔记本电脑(macbook air)上完成的,不需要很长时间。插入虽然需要一些时间,但需要几分钟才能获得 50 万条记录。但是检索和计算却没有。

我们需要更多来完全完整地回答您的问题。可能是数据库的配置错误,例如几乎没有分配内存?

于 2012-06-30T18:34:14.830 回答
-1

我认为问题是您的服务器带宽。拥有一百万行可能至少需要高兆字节的带宽。

于 2012-06-30T16:45:01.993 回答