MySQL使用索引条件

时间:2014-12-23 11:08:41

标签: mysql indexing

我有两个结构表,可以描述如下:

CREATE TABLE `sub_schedule` (
  `ScheduleID` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `ServiceID` bigint(20) unsigned NOT NULL,
  `RunTime` time NOT NULL,
  `Status` char(1) NOT NULL DEFAULT 'A',
  `Telco` text,
  PRIMARY KEY (`ScheduleID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
CREATE TABLE `mt` (
  `MtID` int(15) unsigned NOT NULL AUTO_INCREMENT,
  `ServiceID` bigint(20) unsigned NOT NULL,
  `Moperator` varchar(10) NOT NULL,
  `Cmd` varchar(20) NOT NULL,
  `CreateDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`MtID`),
  KEY `CreateDate` (`CreateDate`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

Mt表是大表,sub_schedule表保存少于500条记录。

当我尝试运行此查询时:

EXPLAIN 
 SELECT m.serviceid
      , m.createdate
      , m.moperator
   FROM mt m
   JOIN sub_schedule ss 
     ON m.serviceid = ss.serviceid 
    AND ss.status = "A" 
    AND ss.telco LIKE CONCAT('%', m.moperator, '%')
  WHERE m.createdate >= addtime((subdate(curdate(), 1)),ss.runtime) 
    AND m.createdate <= addtime((subdate(curdate(), 0)),ss.runtime)
    AND m.cmd LIKE "SUBS%";

它产生这个输出:

id, select_type, table, type, possible_keys, key  , key_len, ref  , rows     , Extra
 1, SIMPLE     , ss   , ALL , NULL         , NULL , NULL   , NULL ,      470 , Using where
 1, SIMPLE     , m    , ALL , CreateDate   , NULL , NULL   , NULL , 57610462 , Range checked for each record (index map: 0x10)

它似乎没有在该查询中使用createdate的索引,这会导致查询执行时间过长。已经尝试使用FORCE INDEX和该查询的不同方法,并尝试将createdate移至ON条件部分并使用FORCE INDEX FOR JOIN。 所以我的问题是:有没有办法让mysql实际使用createdate字段的索引?

1 个答案:

答案 0 :(得分:0)

mt.serviceid上没有索引,因此必须扫描mt中的所有行以满足条件m.serviceid = ss.serviceid。在全表扫描期间,可以并且将检查此表上的其他条件。

mt(serviceid, createdate)mt(createdate, serviceid)上添加索引(不确定哪一个会产生最佳效果)。

注意:如果您决定使用mt(createdate, serviceid)上的索引,那么mt(createdate) becomes superfluous上的索引。