【问题标题】:MySQL using index conditionMySQL使用索引条件
【发布时间】:2014-12-23 11:08:40
【问题描述】:

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

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字段的索引?

【问题讨论】:

  • 你能发布你创建的索引吗?

标签: mysql indexing


【解决方案1】:

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

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

注意:如果您决定使用并在 mt(createdate, serviceid) 上编制索引,则在 mt(createdate) 上编制索引。

【讨论】:

  • 感谢您的回复。我在 mt 表中添加了 serviceid 索引,但它仍然扫描每条记录
  • 查询返回多少行?有多少没有WHERE 子句?当查询返回大多数行时,优化器可能决定不使用索引。另外,请确保您在serviceid createdate(不仅仅是serviceid)上创建了复合索引
  • 不,即使索引在serviceid only 上,这个索引也可以用于 JOIN 条件。我想您的查询只返回表中的大多数行。
  • 我需要仔细检查一下。明天可以提供更明确的结果。感谢您的帮助。
猜你喜欢
  • 2015-04-29
  • 2010-12-13
  • 1970-01-01
  • 2015-04-16
  • 2020-02-17
  • 2017-08-28
  • 1970-01-01
  • 1970-01-01
  • 2023-02-21
相关资源
最近更新 更多