我有两个结构表,可以描述如下:
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
字段的索引?
答案 0 :(得分:0)
mt.serviceid
上没有索引,因此必须扫描mt
中的所有行以满足条件m.serviceid = ss.serviceid
。在全表扫描期间,可以并且将检查此表上的其他条件。
在mt(serviceid, createdate)
或mt(createdate, serviceid)
上添加索引(不确定哪一个会产生最佳效果)。
注意:如果您决定使用mt(createdate, serviceid)
上的索引,那么mt(createdate)
becomes superfluous上的索引。