最近,开课吧码堂的一位同学,遇到了一个让他感到棘手的问题。他在用MySQL查询数据时,发现某个查询语句耗时特别长,而且在扫描表的时候CPU的使用率也很高,这显然不是一个好的迹象。
通过对查询语句进行优化,他发现可以加一个索引,但是在执行查询语句的时候,扫描行数并没有降下来,反而更高了,这是怎么回事呢?
经过调查,我们发现,原来加上的索引并没有被使用,这也是导致扫描行数没有降低的原因。那么为什么索引会失效呢?
CREATE TABLE `test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
SELECT * FROM `test` WHERE `age` >20 AND `name` LIKE '%张%';
看到这个查询语句,大家可能会想到先通过`age`字段的索引来筛选数据,再用`name`字段的索引来进一步缩小查询结果。但是当我们执行这个查询语句时,MySQL却认为使用`age`字段的索引比直接扫描表要慢,所以放弃了这个索引,直接进行了全表扫描,这就是索引失效的典型案例。
针对这种情况,我们可以通过调整查询语句的顺序来避免索引失效。也就是说,我们需要将先筛选出`name`字段符合条件的数据,再通过`age`字段进行筛选。因此,我们可以将查询语句改为:
SELECT * FROM `test` WHERE `name` LIKE '%张%' AND `age` >20;
通过这种方式,我们就可以避免索引失效的问题,提高查询的效率。