Mysql慢查询 - 即使有所有索引

时间:2013-07-25 08:23:11

标签: mysql query-optimization

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 |
+----+-------------+-------+--------+----------------------------------------+------------+---------+---------------------+--------+-------------+

如何更快地进行上述查询 - 它会在慢速查询日志中不断显示 索引出现:

  1. id是流表的自动递增主键。
  2. 流量表的customerId。
  3. 评论表的userEmail。
  4. 评论表上的复合索引(typeId,type)。
  5. 用户电子邮件表(唯一)
  6. 评论表的自动化。
  7. 评论表的addTime。
  8. 行数:
    1.流量 - 150k
    2.注释 - 500k(其中一半自动= 1,其他自动= 0)(除了500之外,所有行的类型值都是'flow') 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 |
    

1 个答案:

答案 0 :(得分:1)

您具有所需的索引以有效地执行联接。但是,看起来MySQL正以较低效的方式加入表格。 EXPLAIN输出显示它正在对flows表执行完整索引扫描,然后加入comments表。

在加入之前首先阅读comments表可能更有效。也就是说,按照您在查询中指定的顺序,以便注释集受到您提供的谓词(可能是您的预期)的限制。

运行OPTIMISE TABLEANALYZE TABLE可以改善查询优化器的决策。特别是在有大幅变化的表格上。

如果查询优化器仍然出错,您可以通过使用SELECT STRAIGHT_JOIN开始语句或将INNER JOIN更改为{{1}来强制按照您在查询中指定的顺序读取表格}。