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 は一度に 1 つのインデックスしか使用できないため、 と の両方にインデックスを作成すると役立つ場合がありFileMD5ますNoCsumMD5

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

複数の列のインデックスに関する情報を次に示します。

MySQL は、インデックス内のすべての列をテストするクエリ、または最初の列、最初の 2 つの列、最初の 3 つの列などだけをテストするクエリに、複数列のインデックスを使用できます。インデックス定義で列を正しい順序で指定すると、単一の複合インデックスで同じテーブルに対する複数の種類のクエリを高速化できます。

短いバージョンでは、MySQL はその順序でのみインデックスを使用できるため、インデックス内の列の順序が重要です (たとえば、上記のインデックスでは、 をテストNoCsumMD5し、 を使用して結果を絞り込むことができますFileMD5)。

ただし、このクエリでどれだけ役立つかはわかりません。気にするのFileMD5は、そうかどうかだけなNULLので..

于 2013-02-01T17:23:05.943 に答える
1

テーブル定義では NULL ではないためFileMD5、クエリを簡略化でき、@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 に答える