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

问题是on indicator_performance_averages.symbol 与on prof.symbolcharacter set utf8不匹配。character set latin1

这可以防止 MySQL 在 prof.symbol 上使用索引。

要获得可用于查询计划的索引,您需要转换谓词中的字符集以匹配列的数据类型。尝试将连接谓词更改为此...

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

(我认为这是正确的语法。我们试图让 MySQL 从 ipa 表中获取 utf8 值,并将其转换为 latin1,然后再查找 prof 表。一个 CAST() 函数也可以使用。)

于 2013-07-11T21:41:01.607 回答