在工作中,如果我们想提高一条语句查询速度,通常都会想对字段建立索引。
但是索引并不是万能的。建立了索引,并不意味着任何查询语句都能走索引扫描。
稍不注意,可能你写的查询语句是会导致索引失效,从而走了全表扫描,虽然查询的结果没问题,但是查询的性能大大降低。
今天就来跟大家盘一盘,发生索引失效的几种场景。
首先介绍一下索引的语法,如何创建,查看,删除索引
索引语法
创建索引 | CREATE [ UNIQUE | FULLTEXT ] INDEX index_name ON table_name ( index_col_name,... ); |
查看索引 | SHOW INDEX FROM table_name; |
删除索引 | DROP INDEX index_name ON table_name; |
在创建好索引之后,我们通过explain关键字来查看该sql语句的执行过程,即在该sql语句前加入explain,explain sql语句;
explain执行计划详解
ld | select查询的序列号,表示查询中执行selet子句或者是操作表的顺序(id相同,执行顺序从上到下;id不同,值越大,越先执行) |
select_type | 表示 SELECT 的类型,常见的取值有 SIMPLE(简单表,即不使用表连接或者子查询)、PRIMARY(主查询,即外层的查询)UNION(UNION 中的第二个或者后面的查询语句)、SUBQUERY(SELECT/WHERE之后包含了子查询)等 |
type | 表示连接类型,性能由好到差的连接类型为NULL、System、cnst、eg ref、ref、range、index、all. |
possible_key | 显示可能应用在这张表上的索引,一个或多个 |
Key | 实际使用的索引,如果为NULL,则没有使用索引。 |
Key_len | 表示索引中使用的字节数,该值为索引字段最大可能长度,并非实际使用长度,在不损失精确性的前提下,长度越短越好, |
rows | MySQL认为必须要执行查询的行数,在innodb引擎的表中,是一个估计值,可能并不总是准确的。 |
filtered | 表示返回结果的行数占需读取行数的百分比,filtered的值越大越好 |
我个人经常关注的几个字段有 type,possible_key,Key,rows
重点给大家讲下索引失效的几种场景
索引失效的几种场景
最左前缀法则 | 如果索引了多列(联合索引》,要遵守最左前缀法则。最左前缀法则指的是查询从索引的最左列开始,并且不跳过索引中的列。 如果跳跃某一列,索引将部分失效(后面的字段索引失效)。 |
范围查询 | 联合索引中,出现范围查询(>,<),范围查询右侧的列索引失效 |
索引列运算 | 不要在索引列上进行运算操作,索引将失效 |
字符串不加引号 | 字符串类型字段使用时,不加引号,索引将失效 |
模糊查询 | 如果仅仅是尾部模糊匹配,索引不会失效。如果是头部模糊匹配,索引失效。 |
or连接的条件 | 用or分割开的条件,如果or前的条件中的列有索引,而后面的列中没有索引,那么涉及的索引都不会被用到 |
查询所有 | 也就是使用select * ,它是会全表扫描,没有用到任何索引,查询效率是非常低的 |
好了,先说这么多吧,后面有时间再给大家演示一下
















