mysql什么情况下sql语句用不到索引

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_43740552/article/details/102625746

1:条件中有or,并且所有条件字段都建了索引,才能用到索引,否则用不到。

explain select * from sdb_b2c_members where mobile='18202139749' or name = '邢进'

这条sql语句中的mobile和name都建了索引,所以用到了索引。
在这里插入图片描述

explain select * from sdb_b2c_members where mobile='18202139749' or point = '3034'

这条sql语句中的mobile字段有索引,但是point字段没索引,所以没用到索引。
在这里插入图片描述
所以:要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引

2:对于多列索引,要遵循最左前缀原则,否则用不到索引(除非这个字段在多列索引之外又建立了单个索引)。
比如,我建了一个组合索引,索引顺序是:a b c d
where a = ‘’;//能用到索引
where a = ‘’ and b = ‘’ and c = ‘’ and d = ‘’;//能用到索引
where a = ‘’ and b=’’ and d = ‘’ //此时d用不到索引
where a = ‘’ and b > 10 //a能用到索引,b用不到
where b = ‘’ //用不到索引

建表:
CREATE TABLE student3(
    id INT(11)  auto_increment,
    name VARCHAR(10) not null,
    age int(10) not null default 0,
    height int(10) not null default 0,
    weight int(10) not null default 0,
    primary key (id),
    key n_a_h_w(name,age,height,weight)
  )ENGINE=INNODB;

跳过联合索引的第一个字段name,直接用第二个字段:发现type列是index,表示进行了全索引扫描。
explain select * from student3 where age = 20;
+----+-------------+----------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
| id | select_type | table    | partitions | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra                    |
+----+-------------+----------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
|  1 | SIMPLE      | student3 | NULL       | index | n_a_h_w       | n_a_h_w | 44      | NULL |    3 |    33.33 | Using where; Using index |
+----+-------------+----------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
1 row in set, 1 warning (0.07 sec)

直接用索引的第一个字段:发现type列是ref,表示用到了索引。
explain select * from student3 where name = 'lbj';
+----+-------------+----------+------------+------+---------------+---------+---------+-------+------+----------+-------------+
| id | select_type | table    | partitions | type | possible_keys | key     | key_len | ref   | rows | filtered | Extra       |
+----+-------------+----------+------------+------+---------------+---------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | student3 | NULL       | ref  | n_a_h_w       | n_a_h_w | 32      | const |    3 |   100.00 | Using index |
+----+-------------+----------+------------+------+---------------+---------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.04 sec)

3:like查询时以%开头,则用不到索引。

4:存在索引列的数据类型有隐形转换,则用不上索引,比如说,列类型是字符串,你存了一个数字进去,但是数字却没加引号,这个就是类型隐形转换。

sdb_b2c_members表的mobile字段,类型是varchar,建了索引。
如果存储的值是18202139749,数据没加引号:
explain select * from sdb_b2c_members where mobile=18202139749;

可以看出这条sql并没有使用到索引。
在这里插入图片描述

我们把where条件里的mobile字段的值加上引号:explain select * from sdb_b2c_members where mobile='18202139749';

可以看出加了引号后就可以用到索引了
在这里插入图片描述
5:where 子句里对索引列上有数学运算,用不上索引。

6:where 子句里对有索引列使用函数,用不上索引。

7:如果mysql估计使用全表扫描要比使用索引快,则不使用索引。

猜你喜欢

转载自blog.csdn.net/weixin_43740552/article/details/102625746