MySql选择使用错误索引的组合索引

时间:2019-02-03 07:00:05

标签: mysql

我有下表:

CREATE TABLE IF NOT EXISTS `dbname`.`test_table` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(80) NOT NULL,      
  `confidence` FLOAT NULL DEFAULT NULL,
  `task_id` INT(11) NOT NULL,
  `check_status` INT(11) NULL DEFAULT NULL,
  `deleted` BOOLEAN NOT NULL DEFAULT 0,
  `createdAt` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  `modifiedAt` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
   PRIMARY KEY (`id`),
   INDEX task_status (task_id, check_status),
   INDEX task_name_conf(task_id, name, confidence))
ENGINE = InnoDB
AUTO_INCREMENT = 11
DEFAULT CHARACTER SET = utf8;

我有以下经常使用的查询:

select * from test_table where task_id = 13 and check_status = 1;
select name from test_table
    where task_id = 13
    AND name like '%name%'
        order by confidence desc;

如您所见,我创建了2索引以加速上述查询。当我在第二个查询上执行explain时,尽管task_statustask_name_conf都被列为possible_keys,但key字段仅包含task_statusref字段也只有一个const,这意味着此处仅使用task_id

为什么不使用task_name_conf索引执行第二个查询?

编辑:

我得到它的名字 like ,然后按其排序不能利用该索引。只有平等才行。 name ='name' order by confidence利用了task_name_conf索引。但是奇怪的是select name from test_table where task_id= and name= and confidence=(标准3等于)再次无法使用索引task_name_conf

1 个答案:

答案 0 :(得分:1)

name like '%name%'条件不能使用任何索引,因为您要查找的值可以在字段中的任何位置。

confidence字段是task_name_conf索引的最后一个name字段,因此优化器也不能使用该索引对confidence进行排序。

这意味着任何索引仅覆盖task_id字段,因此mysql选择较小(较少字段)的索引。

您要么需要将name字段完全移出第二个索引。或者,如果名称搜索是最昂贵的标准,则考虑使用全文索引并搜索而不是简单的psttern匹配。