2013-07-25 42 views
3
mysql> explain 
    select c.userEmail,f.customerId 
    from comments c 
     inner join flows f 
     on (f.id = c.typeId) 
     inner join users u 
     on (u.email = c.userEmail) 
    where c.addTime >= 1372617000 
     and c.addTime <= 1374776940 
     and c.type = 'flow' 
     and c.automated = 0; 
+----+-------------+-------+--------+----------------------------------------+------------+---------+---------------------+--------+-------------+ 
| id | select_type | table | type | possible_keys       | key  | key_len | ref     | rows | Extra  | 
+----+-------------+-------+--------+----------------------------------------+------------+---------+---------------------+--------+-------------+ 
| 1 | SIMPLE  | f  | index | PRIMARY        | customerId | 4  | NULL    | 144443 | Using index | 
| 1 | SIMPLE  | c  | ref | userEmail_idx,addTime,automated,typeId | typeId  | 198  | f.id,const |  1 | Using where | 
| 1 | SIMPLE  | u  | eq_ref | email         | email  | 386  | c.userEmail |  1 | Using index | 
+----+-------------+-------+--------+----------------------------------------+------------+---------+---------------------+--------+-------------+ 

如何使上述查詢更快 - 它不斷顯示在慢查詢日誌中。
指標呈現:Mysql慢速查詢 - 即使使用所有索引

  1. id是流表的自動遞增主鍵。
  2. 流表的customerId。
  3. 評論表的userEmail。
  4. 評論表上的複合索引(typeId,type)。
  5. 用戶電子郵件表(唯一)
  6. 自動化評論表。
  7. 評論表addTime。行

數:
1.流動 - 150K
2.評論 - 500K(其中一半有自動= 1和其他人已經自動化= O)(也類型的值是「流動」的所有除了500行)
3.用戶 - 50種

表模式:

users | CREATE TABLE `users` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `email` varchar(128) NOT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `email` (`email`) 
) ENGINE=InnoDB AUTO_INCREMENT=56 DEFAULT CHARSET=utf8 

comments | CREATE TABLE `comments` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `userEmail` varchar(128) DEFAULT NULL, 
    `content` mediumtext NOT NULL, 
    `addTime` int(11) NOT NULL, 
    `typeId` int(11) NOT NULL, 
    `automated` tinyint(4) NOT NULL, 
    `type` varchar(64) NOT NULL, 
    PRIMARY KEY (`id`), 
    KEY `userEmail_idx` (`userEmail`), 
    KEY `addTime` (`addTime`), 
    KEY `automated` (`automated`), 
    KEY `typeId` (`typeId`,`type`) 
) ENGINE=InnoDB AUTO_INCREMENT=572410 DEFAULT CHARSET=utf8 | 


flows | CREATE TABLE `flows` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `type` varchar(32) NOT NULL, 
    `status` varchar(128) NOT NULL, 
    `customerId` int(11) NOT NULL, 
    `createTime` int(11) NOT NULL, 
    PRIMARY KEY (`id`), 
    KEY `flowType_idx` (`type`), 
    KEY `customerId` (`customerId`), 
    KEY `status` (`status`), 
    KEY `createTime` (`createTime`), 
) ENGINE=InnoDB AUTO_INCREMENT=134127 DEFAULT CHARSET=utf8 | 
+6

嘗試在'(自動化,類型,addTime)上添加一個索引' –

+0

忘了提及,addTime上已經有一個索引。 – dharm0us

+0

剛剛在註釋上運行優化表,解釋輸出現在顯示的行數較少。我會看看它是否也加快了應用程序上下文中的查詢速度。 – dharm0us

回答

1

你所需要的指標進行有效的連接。但是,它看起來像MySQL以低效的方式加入表格。 EXPLAIN輸出顯示它正在對flows表進行完整索引掃描,然後加入comments表。

在加入之前先閱讀comments表可能會更高效。也就是說,按照您在查詢中指定的順序,使得註釋集受到您提供的謂詞(可能是您的意圖)的限制。

運行OPTIMISE TABLEANALYZE TABLE可以改善查詢優化程序所做的決定。特別是在有大量變化的表格上。

如果查詢優化器仍然出錯,您可以通過以SELECT STRAIGHT_JOIN開始語句或將INNER JOIN更改爲STRAIGHT_JOIN來強制按照您在查詢中指定的順序讀取表。

+0

感謝您指出straight_join。儘管我在某處讀到這不是一個理想的解決方案 - 但它有助於優化另一個查詢。 – dharm0us