5

質問

MyISAMベースのテーブルにGROUPBY最適化がない理由を誰かが知っていますか?(私はこのバージョンを使用しています:5.1.49-3)

テストテーブル

CREATE TABLE `_test2_innodb` (
    `i` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `n` smallint(5) unsigned NOT NULL,
    `t` int(10) unsigned NOT NULL,
    `v` smallint(6) NOT NULL,
    PRIMARY KEY (`i`),
    KEY `i_n` (`n`),
    KEY `i_t` (`t`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

CREATE TABLE `_test2_myisam` (
    `i` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `n` smallint(5) unsigned NOT NULL,
    `t` int(10) unsigned NOT NULL,
    `v` smallint(6) NOT NULL,
    PRIMARY KEY (`i`),
    KEY `i_n` (`n`),
    KEY `i_t` (`t`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1

クエリをテストする

SELECT MAX(i) FROM _test2_myisam GROUP BY n;

SELECT MAX(i) FROM _test2_innodb GROUP BY n;

結果

id, select_type, table, type, poss_keys, key, key_len, ref, rows, extra

1, SIMPLE, _test2_myisam , ALL, , , , , 19998, Using temporary; Using filesort

1, SIMPLE, _test2_innodb, index, , i_n, 2, , 20024, Using index

問題は、MyISAMを使用している場合、全表スキャンが実行されることです。これには、大きなテーブルでは数時間かかります...また、MySQLのドキュメントには、実装が異なるテーブルエンジンについては何も記載されていません(http://dev。 mysql.com/doc/refman/5.0/en/group-by-optimization.html)。なぜこれが内部で異なって処理されるのか誰かが知っていますか?

(注:いいえ、InnoDBに切り替えるのは良い解決策ではありません)ありがとう

4

2 に答える 2

3

2つのテーブルの違いは、一見同じ定義にもかかわらず、MyISAMテーブルは「ヒープ」であるのに対し、InnoDBテーブルはクラスター化された組織化テーブルであるということです。たとえば、クラスター化インデックスはテーブル(通常は主キー、(i)ここではインデックス)です。

異なる実行プランを引き起こす他の違いは、InnoDBでは、すべての非クラスター化インデックス((n)この場合はインデックス)にクラスター化インデックスの列(この場合)も含まれる(i)ため、全表スキャンは必要ありません。

つまり、(n)InnoDBインデックスはMyISAMインデックスとほぼ同等(n, PK)です。

MyISAMエンジンは、インデックスの全表スキャンまたはインデックススキャンを実行してから、テーブルもスキャンする必要があります(列(n)の値を取得するため)。iしたがって、最初のプランを選択します(MAX値を見つけるためのフルスキャン+ファイルソート)。


(n, i)MyISAMテーブルにインデックスを追加した後、テストを再実行します。

ALTER TABLE _test2_myisam
    ADD INDEX n_i (n, i) ;
于 2012-10-31T11:44:39.960 に答える
0

これは、InnoDBが主キーに基づいてインデックス編成された方法で格納されているためです。したがって、テーブルスキャンと主キースキャンはまったく同じものになります。MyISAMにとって残念なことに、これは当てはまりません。ファイルソートを実行する必要があります。

于 2012-10-31T11:39:36.003 に答える