mysql什麼情況下sql語句用不到索引

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估計使用全表掃描要比使用索引快,則不使用索引。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章