0

我有一个有 300 万行和 6 列的表。

表结构:

| Sample | CREATE TABLE `sample` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `FileMD5` varchar(32) NOT NULL,
  `NoCsumMD5` varchar(32) NOT NULL,
  `SectMD5` varchar(32) NOT NULL,
  `SectNoResMD5` varchar(32) NOT NULL,
  `ImpMD5` varchar(32) NOT NULL,
  `Overlay` tinyint(1) NOT NULL DEFAULT '1',
  PRIMARY KEY (`ID`),
  KEY `FileMD5` (`FileMD5`),
  KEY `NoCsumMD5` (`NoCsumMD5`)
) ENGINE=InnoDB AUTO_INCREMENT=3073630 DEFAULT CHARSET=latin1 |

临时表值:

mysql> SHOW VARIABLES LIKE 'tmp_table_size';
+----------------+----------+
| Variable_name  | Value    |
+----------------+----------+
| tmp_table_size | 16777216 |
+----------------+----------+
1 row in set (0.00 sec)
mysql> SHOW VARIABLES LIKE 'max_heap_table_size';
+---------------------+----------+
| Variable_name       | Value    |
+---------------------+----------+
| max_heap_table_size | 16777216 |
+---------------------+----------+
1 row in set (0.00 sec)

我的查询

mysql> explain SELECT NoCsumMD5,Count(FileMD5) 
FROM Sample GROUP BY NoCsumMD5 
HAVING Count(FileMD5) > 10 ORDER BY Count(FileMD5) Desc ;
+----+-------------+--------+-------+---------------+-----------+---------+------+---------+---------------------------------+
| id | select_type | table  | type  | possible_keys | key       | key_len | ref  | rows    | Extra                           |
+----+-------------+--------+-------+---------------+-----------+---------+------+---------+---------------------------------+
|  1 | SIMPLE      | Sample | index | NULL          | NoCsumMD5 | 34      | NULL | 2928042 | Using temporary; Using filesort |
+----+-------------+--------+-------+---------------+-----------+---------+------+---------+---------------------------------+

如何优化此查询。即使在 10 分钟后,它也不会产生任何输出。

我觉得我已经索引了正确的列并为临时表提供了足够的内存。

4

2 回答 2

1

我不确定这是否会有所帮助,但 MySQL 一次只能使用一个索引,因此在两者上创建索引可能会有所帮助FileMD5NoCsumMD5

KEY `someName` (`NoCsumMD5`, `FileMD5`),

以下是有关多列索引的一些信息

MySQL 可以将多列索引用于测试索引中所有列的查询,或者只测试第一列、前两列、前三列等的查询。如果您在索引定义中以正确的顺序指定列,则单个复合索引可以加快对同一张表的多种查询。

简短的版本是索引中列的顺序很重要,因为 MySQL 只能按该顺序使用索引(例如,在我上面给出的索引中,它可以 test NoCsumMD5,然后使用 缩小结果FileMD5)。

不过,我不确定它对这个查询有多大帮助,因为你关心的只是FileMD5是否NULL..

于 2013-02-01T17:23:05.943 回答
1

由于FileMD5在您的表定义中不是 NULL,因此可以简化查询,并且您不需要@brendan-long 建议的复合索引(NoCsumMD5 索引就足够了):

SELECT NoCsumMD5, Count(*) as cnt 
FROM Sample
GROUP BY NoCsumMD5 
HAVING cnt > 10
ORDER BY cnt DESC;
于 2013-02-01T17:44:26.680 回答