2013-07-11 102 views
2

我有一個MySQL查詢運行非常緩慢,因爲它沒有使用連接鍵上的索引。我的表結構的優化器沒有使用索引有什麼問題?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 
+0

MySQl在JOIN上使用'indicator_performance_averages.idx_symbol'索引。它只會在JOIN上使用一個索引,因爲它已經知道另一端的值。 – 2013-07-11 21:21:20

+0

使用什麼字符集編碼各自的「符號」列? – eggyal

+0

我們期望'prof.symbol'上的唯一鍵在計劃的possible_keys列中顯示。這裏沒有足夠的信息來調試問題。我認爲我們需要'SHOW CREATE TABLE'的輸出來表示這兩個表,以便發現問題。由於這是一個VARCHAR列,可能的嫌疑犯是字符集或排序規則的區別。 – spencer7593

回答

0

的問題是indicator_performance_averages.symbol不匹配prof.symbol的character set latin1character set utf8

這可以防止MySQL使用prof.symbol上的索引。

要使索引可用於查詢計劃,您需要轉換謂詞中的字符集以匹配列的數據類型。試着改變連接謂詞這...

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

(我認爲這是正確的語法。我們正在努力使發生是MySQL採取從IPA表utf8的價值,將其轉換成latin1,然後再查找prof表。還可以使用CAST()函數。)

+0

謝謝。我使用navicat調整了表格的字符集,但沒有意識到這不會調整個別字段。 –

+0

@Colin M:我猶豫了,建議你改變列的字符集,因爲可能有這樣設置的原因。是的,表格的字符集是添加新列時將使用的默認值。當創建列時,字符集在每個列級別上都會被指定。但是更方便的是,不必在每個字符列上指定它,並讓該列「繼承」來自表的設置,該表在創建時從創建時從數據庫繼承而來,該數據庫在創建時從該實例繼承。 – spencer7593