1.联合索引
对于多列索引,过滤条件要使用索引必须按照索引建立时的顺序,依次满足,一旦跳过某个字段,索引后面的字段都无法被使用。
例如以下情况,索引从左到右的顺序为age,classId,name,但是在查询时跳过了age,因此该查询无法使用索引。
CREATE INDEX idx_age_classid_name ON student(age,classId,name);
SELECT SQL_NO_CACHE * FROM student WHERE student.classId=1 AND student.name = 'abcd';
2. 使用函数
查询条件中使用了函数会导致索引失效
例如以下情况,使用了函数导致索引失效
SELECT SQL_NO_CACHE * FROM student WHERE LEFT(student.name,3) = 'abc';
3. 含有计算
查询条件中含有计算会导致索引失效
例如以下情况:
SELECT SQL_NO_CACHE id, stuno, NAME FROM student WHERE stuno+1 = 900001;
4. 类型转换
查询条件两边类型不同,需要自动或主动的进行类型转换,会导致索引失效。例如以下情况,name字段假设为字符串,但查询条件右边为数字123,这时会自动进行类型转换进行比较,因此无法使用索引。
-- 假设name字段有索引且name字段类型为字符串
SELECT SQL_NO_CACHE * FROM student WHERE name=123;
5. 范围条件右边的列索引失效
当有联合索引且查询条件含有范围比较时,比如:(<) (<=) (>) (>=) 和 between 等,索引中被比较范围的列的右边的不能使用。
例如下列情况,索引从左到右包含age,classId,name,但在查询条件中classId为范围比较,因此索引中的name列无法使用,因为在索引中name在列classId的右边。
create index idx_age_name_classId on student(age,classId,name);
SELECT SQL_NO_CACHE * FROM student
WHERE student.age=30 AND student.classId>20 AND student.name = 'abc' ;
6. 不等于(!= 或者<>)索引失效
查询条件中包含不等于的判断时,索引无法使用。
例如:
CREATE INDEX idx_name ON student(NAME);
SELECT SQL_NO_CACHE * FROM student WHERE student.name != 'abc';
7. is null可以使用索引,is not null无法使用索引
在查询条件中,IS NULL可以使用索引,而IS NOT NULL 无法使用索引。例如:
SELECT SQL_NO_CACHE * FROM student WHERE age IS NOT NULL;
8. like以通配符%开头索引失效
在使用LIKE关键字进行查询的查询语句中,如果匹配字符串的第一个字符为’%‘,索引就不会起作用。只有’%'不在第一个位置,索引才会起作用。例如:
--可以使用索引
SELECT SQL_NO_CACHE * FROM student WHERE name LIKE 'ab%';
--无法使用索引
SELECT SQL_NO_CACHE * FROM student WHERE name LIKE '%ab%';
9. OR 前后存在非索引的列,索引失效
在WHERE子句中,如果在OR前的条件列进行了索引,而在OR后的条件列没有进行索引,那么索引会失效。也就是说,OR前后的两个条件中的列都是索引时,查询中才使用索引。
因为OR的含义就是两个只要满足一个即可,因此只有一个条件列进行了索引是没有意义的,只要有条件列没有进行索引,就会进行全表扫描,因此所以的条件列也会失效。
例如以下情况,如果classId字段上没有索引,那么该查询语句无法使用索引。
SELECT SQL_NO_CACHE * FROM student WHERE age = 10 OR classid = 100;
10. 字符集不同
统一使用utf8mb4( 5.5.3版本以上支持)兼容性更好,统一字符集可以避免由于字符集转换产生的乱码。不同的字符集进行比较前需要进行转换会造成索引失效。
注意:
(1)最好让主键自增 ,让存储引擎自己为表生成主键,而不是我们手动插入 ,这样在插入新的数据时不需要页面分裂,避免性能损耗。
(2)将范围查询条件放置语句最后,这样可以避免上述第五点情况。
(3)最好在设计数据库的时候就将字段设置为 NOT NULL 约束,比如你可以将 INT 类型的字段,默认值设置为0。将字符类型的默认值设置为空字符串(‘’)。
(4)对于单列索引,尽量选择针对当前query过滤性更好的索引。文章来源:https://www.toymoban.com/news/detail-806758.html
(5)在选择组合索引的时候,当前query中过滤性最好的字段在索引字段顺序中,位置越靠前越好。文章来源地址https://www.toymoban.com/news/detail-806758.html
到了这里,关于SQL笔记 -- 索引失效情况的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!