4

MyISAM テーブルに MySQL の数百万のレコードを含むテーブルがあります。非常に単純化すると、次のようになります。

CREATE TABLE `test` (
  `text` varchar(5) DEFAULT NULL,
  `number` int(5) DEFAULT NULL,
  KEY `number` (`number`) USING BTREE,
  KEY `text_number` (`text`,`number`) USING BTREE
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

次のデータが入力されます。

INSERT INTO `test` VALUES ('abcd', '1');
INSERT INTO `test` VALUES ('abcd', '2');
INSERT INTO `test` VALUES ('abcd', '3');
INSERT INTO `test` VALUES ('abcd', '4');
INSERT INTO `test` VALUES ('bbbb', '1');
INSERT INTO `test` VALUES ('bbbb', '2');
INSERT INTO `test` VALUES ('bbbb', '3');

次のクエリを実行すると:

EXPLAIN SELECT * FROM `test` WHERE (`text` = 'bbbb' AND `number` = 2)

使用するキーとして 'number' を返します。しかし、次のクエリ:

EXPLAIN SELECT * FROM `test` WHERE (`text` = 'bbbb' AND `number` = 1)

使用するキーとして「text_number」を返します。これは、この結合されたキーが WHERE の 2 つの列と正確に一致するため、より理にかなっています。これらの量のレコードではパフォーマンスは問題になりませんが、数百万のレコードでは、'text' インデックスを使用するクエリは 4 秒かかり、'text_number' インデックスを使用するクエリは数ミリ秒で終了します。

これについて論理的な説明はありますか?MySQL が使用するインデックスを変更するにはどうすればよいですか? USE INDEX を使用できることはわかっていますが、MySQL がクエリを実行するための最適なプランを見つけられるようにしたいと考えています。これは MySQL 5.1 と 5.5 で同じ結果です。

4

2 に答える 2

1

一部のクエリがパフォーマンスのゲーム チェンジャーになると予想される場合は、次のような独自のインデックスを使用することをお勧めします。

EXPLAIN SELECT * FROM `test` USE INDEX (number) WHERE (`text` = 'bbbb' AND `number` = 1);
or
EXPLAIN SELECT * FROM `test` USE INDEX (text_number) WHERE (`text` = 'bbbb' AND `number` = 1);

一般に、ほとんどのクエリでは組み込みのクエリ オプティマイザーを使用できますが、重要または問題のあるクエリについては、詳しく調べることをお勧めします。

于 2013-09-12T15:07:36.447 に答える
1

パフォーマンスを向上させることができる 2 つのこと:

  1. ANALYZE TABLEオプティマイザのインデックス統計を更新して、現在のキー分布を認識できるようにします。オプティマイザの統計生成は、さまざまな方法で制御できます。
  2. フィールドが反転された 2 番目のカバリング インデックスを作成します。現実の世界では、これには、3 つまたは 4 つの列のセットに対して最適な 1 つまたは 2 つのカバリング インデックスを見つけ出すことが含まれます。これは、ベンチマークとEXPLAIN分析を通じて到達するものです。それを行うためのアドバイスについては、この回答をご覧ください。
于 2013-09-12T15:09:13.127 に答える