2014-10-08 112 views
2

我有2個表 - profile與1,500,000記錄和indicator_trades與12,000,000記錄。以下查詢返回0個結果,大約需要10秒才能完成。MySQL查詢不正確使用索引?

SELECT `trd`.`symbol`, `p`.`type` 
FROM `indicator_trades` AS `trd` 
INNER JOIN `profile` AS `p` ON `p`.`symbol` = `trd`.`symbol` 
WHERE `start_date` >= '2014-09-17' AND `p`.`type` = 2 

DESCRIBE結果:

+----+-------------+-------+--------+-----------------------+------------+---------+--------------------------+------+-------------+ 
| id | select_type | table | type | possible_keys   | key  | key_len | ref      | rows | Extra  | 
+----+-------------+-------+--------+-----------------------+------------+---------+--------------------------+------+-------------+ 
| 1 | SIMPLE  | trd | range | IDX_symbol,start_date | start_date | 4  | NULL      | 3662 | Using where | 
| 1 | SIMPLE  | p  | eq_ref | IDX_symbol,type  | IDX_symbol | 34  | barchart_data.trd.symbol | 1 | Using where | 
+----+-------------+-------+--------+-----------------------+------------+---------+--------------------------+------+-------------+ 

10秒似乎是一個異常長的時間,這個查詢時,它使用的密鑰,但它只是花這麼長時間從該1200萬,大肆削減3662個記錄indicator_trades表?

SHOW上創建兩個表:

CREATE TABLE `indicator_trades` (
    `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, 
    `symbol` varchar(32) NOT NULL, 
    `indicator_code` varchar(10) NOT NULL, 
    `start_date` date DEFAULT NULL, 
    `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
    PRIMARY KEY (`id`), 
    KEY `IDX_symbol` (`symbol`) USING BTREE, 
    KEY `start_date` (`start_date`), 
    KEY `indicator_code` (`indicator_code`) 
) ENGINE=InnoDB AUTO_INCREMENT=12582721 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT | 

CREATE TABLE `profile` (
    `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, 
    `symbol` varchar(32) NOT NULL, 
    `type` int(11) DEFAULT NULL, 
    `lastupdate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `IDX_symbol` (`symbol`) USING BTREE, 
    KEY `type` (`type`), 
    KEY `exchange` (`exchange`) 
) ENGINE=InnoDB AUTO_INCREMENT=320948248 DEFAULT CHARSET=latin1 
+0

它需要連接1200萬行。我認爲這是內部連接,使它變慢。 – 2014-10-08 20:28:13

+0

@ S.Pols不應該只需要連接3662條記錄,因爲優化器應該在加入之前減少WHERE的數據集? – 2014-10-08 20:36:08

+1

這聽起來像'innodb_buffer_pool_size'變量是非常低的,你正在擊中磁盤而不是RAM。 'SHOW VARIABLES LIKE'%buffer_pool%';'show? – 2014-10-09 07:33:56

回答

0

在第一期待您的查詢要快,也被解釋輸出描述。

不能避免磁盤的讀取,因爲你需要得到一個字段,它是不是在所使用的指數(例如:使用索引start_date,但需要蘆葦symbol場;採用symbol指數,但閱讀type場)。

此外,您需要確保所有索引都加載到內存中(buffer_pool設置允許您增加它)。

您的查詢可以寫成這樣(我認爲同樣的性能應該預計):

SELECT `p`.`symbol`, 
     2 AS `type` 
FROM `profile` AS `p` 
WHERE `p`.`symbol` IN (SELECT DISTINCT(`trd`.`symbol`) 
         FROM `indicator_trades` AS `trd` 
         WHERE `trd`.`start_date` >= '2014-09-17') 
     AND `p`.`type` = 2 

但是你可以運行子查詢,並讓我們知道什麼是它的速度:

SELECT DISTINCT(`trd`.`symbol`) 
          FROM `indicator_trades` AS `trd` 
          WHERE `trd`.`start_date` >= '2014-09-17'