2

結合キーのインデックスを使用していないため、実行速度が非常に遅い MySQL クエリがあります。オプティマイザーがインデックスを使用していないテーブル構造の何が問題になっていますか?

mysql> EXPLAIN SELECT *  FROM indicator_performance_averages
LEFT OUTER JOIN `prof` ON (`prof`.`symbol` = indicator_performance_averages.`symbol`) 
WHERE (indicator_performance_averages.`symbol` = 'ZCN13');
+----+-------------+--------------------------------+-------+---------------+------------+---------+-------+---------+-------+
| id | select_type | table                          | type  | possible_keys | key        | key_len | ref   | rows    | Extra |
+----+-------------+--------------------------------+-------+---------------+------------+---------+-------+---------+-------+
|  1 | SIMPLE      | indicator_performance_averages | const | idx_symbol    | idx_symbol | 98      | const |       1 |       |
|  1 | SIMPLE      | prof                           | ALL   | NULL          | NULL       | NULL    | NULL  | 1102075 |       |
+----+-------------+--------------------------------+-------+---------------+------------+---------+-------+---------+-------+

mysql> DESCRIBE indicator_performance_averages;
+--------------------+------------------+------+-----+---------+----------------+
| Field              | Type             | Null | Key | Default | Extra          |
+--------------------+------------------+------+-----+---------+----------------+
| id                 | int(11) unsigned | NO   | PRI | NULL    | auto_increment |
| symbol             | varchar(32)      | NO   | UNI | NULL    |                |
| date               | date             | YES  |     | NULL    |                |
| last_update        | timestamp        | YES  |     | NULL    |                |
+--------------------+------------------+------+-----+---------+----------------+

mysql> DESCRIBE prof;
+---------------+---------------------+------+-----+---------------------+----------------+
| Field         | Type                | Null | Key | Default             | Extra          |
+---------------+---------------------+------+-----+---------------------+----------------+
| id            | bigint(20) unsigned | NO   | PRI | NULL                | auto_increment |
| symbol        | varchar(32)         | NO   | UNI | NULL                |                |
| name          | varchar(128)        | NO   |     | NULL                |                |
| lastupdate    | datetime            | NO   |     | 0000-00-00 00:00:00 |                |
+---------------+---------------------+------+-----+---------------------+----------------+

編集: 両方のテーブルに SHOW CREATE TABLE を追加:

CREATE TABLE `indicator_performance_averages` (
  `id` int(11) unsigned NOT NULL auto_increment,
  `symbol` varchar(32) character set utf8 NOT NULL,
  `date` date default NULL,
  `last_update` timestamp NULL default NULL,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `idx_symbol` (`symbol`)
) ENGINE=InnoDB AUTO_INCREMENT=6719 DEFAULT CHARSET=latin1

CREATE TABLE `prof` (
  `id` bigint(20) unsigned NOT NULL auto_increment,
  `symbol` varchar(32) NOT NULL,
  `name` varchar(128) NOT NULL,
  `lastupdate` datetime NOT NULL default '0000-00-00 00:00:00',
  PRIMARY KEY  (`id`),
  UNIQUE KEY `id_UNIQUE` (`id`),
  UNIQUE KEY `IDX_symbol` (`symbol`),
) ENGINE=InnoDB AUTO_INCREMENT=37736071 DEFAULT CHARSET=latin1
4

1 に答える 1

0

問題は、 indicator_performance_averages.symbol がprof.symbolcharacter set utf8と一致しないことです。character set latin1

これにより、MySQL が prof.symbol のインデックスを使用できなくなります。

クエリ プランで使用できるインデックスを取得するには、列のデータ型に一致するように述語の文字セットを変換する必要があります。結合述語をこれに変更してみてください...

ON (`prof`.`symbol` = CONVERT(indicator_performance_averages.`symbol` USING latin1)

(これは正しい構文だと思います。私たちが実現しようとしているのは、MySQL が、prof テーブルを検索する前に、ipa テーブルから utf8 値を取得し、それを latin1 に変換することです。CAST() 関数も使えます。)

于 2013-07-11T21:41:01.607 に答える