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