mysql 有索引 不被使用,索引在什么情况下不会被使用?

搜索热词

索引可以提高查询的速度,但并不是使用带有索引的字段查询时,索引都会起作用。使用索引有几种特殊情况,在这些情况下,有可能使用带有索引的字段查询时,索引并没有起作用,下面重点介绍这几种特殊情况。

1. 查询语句中使用LIKE关键字

在查询语句中使用 LIKE 关键字进行查询时,如果匹配字符串的第一个字符为“%”,索引不会被使用。如果“%”不是在第一个位置,索引就会被使用。

例 1

为了便于理解,我们先查询 tb_student 表中的数据,sql 语句和运行结果如下:

MysqL> SELECT * FROM tb_student;

+----+------+------+------+

| id | name | age | sex |

+----+------+------+------+

| 1 | 张三 | 12 | 男 |

| 2 | 李四 | 12 | 男 |

| 3 | 王五 | 13 | 女 |

| 4 | 张四 | 13 | 女 |

| 5 | 王四 | 15 | 男 |

| 6 | 赵六 | 12 | 女 |

+----+------+------+------+

6 rows in set (0.03 sec)

下面在查询语句中使用 LIKE 关键字,且匹配的字符串中含有“%”符号,使用 EXPLAIN 分析查询情况,sql 语句和运行结果如下:

MysqL> EXPLAIN SELECT * FROM tb_student WHERE name LIKE '%四'\G

*************************** 1. row ***************************

id: 1

select_type: SIMPLE

table: tb_student

partitions: NULL

type: ALL

possible_keys: NULL

key: NULL

key_len: NULL

ref: NULL

rows: 6

filtered: 16.67

Extra: Using where

1 row in set,1 warning (0.01 sec)

MysqL> CREATE INDEX index_name ON tb_student(name);

Query OK,6 rows affected (0.13 sec)

MysqL> EXPLAIN SELECT * FROM tb_student WHERE name LIKE '李%'\G

*************************** 1. row ***************************

id: 1

select_type: SIMPLE

table: tb_student

partitions: NULL

type: range

possible_keys: index_name

key: index_name

key_len: 77

ref: NULL

rows: 1

filtered: 100.00

Extra: Using index condition

1 row in set,1 warning (0.00 sec)

第一个查询语句执行后,rows 参数的值为 6,表示这次查询过程中查询了 6 条记录;第二个查询语句执行后,rows 参数的值为 1,表示这次查询过程只查询 1 条记录。同样是使用 name 字段进行查询,因为第一个查询语句的 LIKE 关键字后的字符串是以“%”开头的,所以第一个查询语句没有使用索引,而第二个查询语句使用了索引 index_name。

2. 查询语句中使用多列索引

多列索引是在表的多个字段上创建一个索引,只有查询条件中使用了这些字段中的第一个字段,索引才会被使用。

例 2

在 name 和 age 两个字段上创建多列索引,并验证多列索引的使用情况,sql 语句和运行结果如下:

MysqL> CREATE INDEX index_name_age ON tb_student(name,age);

Query OK,6 rows affected (0.11 sec)

MysqL> EXPLAIN SELECT * FROM tb_student WHERE name LIKE '李%'\G

*************************** 1. row ***************************

id: 1

select_type: SIMPLE

table: tb_student

partitions: NULL

type: range

possible_keys: index_name_age

key: index_name_age

key_len: 77

ref: NULL

rows: 1

filtered: 100.00

Extra: Using index condition

1 row in set,1 warning (0.05 sec)

MysqL> EXPLAIN SELECT * FROM tb_student WHERE age LIKE '12'\G

*************************** 1. row ***************************

id: 1

select_type: SIMPLE

table: tb_student

partitions: NULL

type: ALL

possible_keys: NULL

key: NULL

key_len: NULL

ref: NULL

rows: 6

filtered: 16.67

Extra: Using where

1 row in set,1 warning (0.00 sec)

第一条查询语句的查询条件使用了 name 字段,分析结果显示 rows 参数的值为 1,且查询过程中使用了 index_name_age 索引。第二条查询语句的查询条件使用了 age 字段,结果显示 rows 参数的值为 6,且 key 参数的值为 NULL,这说明第二个查询语句没有使用索引。

因为 name 字段是多列索引的第一个字段,所以只有查询条件中使用了 name 字段才会使 index_name_age 索引起作用。

3. 查询语句中使用OR关键字

查询语句只有 OR 关键字时,如果 OR 前后的两个条件的列都是索引,那么查询中将使用索引。如果 OR 前后有一个条件的列不是索引,那么查询中将不使用索引。

例 3

下面演示 OR 关键字的使用。

MysqL> EXPLAIN SELECT * FROM tb_student WHERE name='张三' or sex='男'\G

*************************** 1. row ***************************

id: 1

select_type: SIMPLE

table: tb_student

partitions: NULL

type: ALL

possible_keys: index_name,index_name_age

key: NULL

key_len: NULL

ref: NULL

rows: 6

filtered: 30.56

Extra: Using where

1 row in set,1 warning (0.06 sec)

MysqL> EXPLAIN SELECT * FROM tb_student WHERE name='张三' or id='12'\G

*************************** 1. row ***************************

id: 1

select_type: SIMPLE

table: tb_student

partitions: NULL

type: index_merge

possible_keys: PRIMARY,index_name,index_name_age

key: index_name,PRIMARY

key_len: 77,4

ref: NULL

rows: 2

filtered: 100.00

Extra: Using union(index_name,PRIMARY); Using where

1 row in set,1 warning (0.01 sec)

由于 sex 字段没有索引,所以第一条查询语句没有使用索引;name 字段和 id 字段都有索引,所以第二条查询语句使用了 index_name 和 PRIMARY 索引 。

总结

使用索引查询记录时,一定要注意索引的使用情况。例如,LIKE 关键字配置的字符串不能以“%”开头;使用多列索引时,查询条件必须要使用这个索引的第一个字段;使用 OR 关键字时,OR 关键字连接的所有条件都必须使用索引。

总结

以上是编程之家为你收集整理的索引在什么情况下不会被使用?全部内容,希望文章能够帮你解决索引在什么情况下不会被使用?所遇到的程序开发问题。

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值