• MySQL学习笔记(八 单表使用索引常见的索引失效 )


    MySQL学习笔记目录

    1. 全值匹配我最爱

    1.1 有以下 SQL 语句

    EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE emp.age=30
    EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE emp.age=30 and deptid=4
    EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE emp.age=30 and deptid=4 AND emp.name = 'abcd'
    
    • 1
    • 2
    • 3

    1.2 建立索引

    CREATE INDEX idx_age_deptid_name ON emp(age,deptid,NAME);
    
    • 1

    在这里插入图片描述

    ​ 结论:全职匹配我最爱指的是,查询的字段按照顺序在索引中都可以匹配到!

    在这里插入图片描述

    ​ SQL 中查询字段的顺序,跟使用索引中字段的顺序,没有关系。优化器会在不影响 SQL 执行结果的前提下,给 你自动地优化。

    2. 最佳左前缀法则

    在这里插入图片描述

    ​ 查询字段与索引字段顺序的不同会导致,索引无法充分使用,甚至索引失效

    ​ 原因:使用复合索引,需要遵循最佳左前缀法则,即如果索引了多列,要遵守最左前缀法则。指的是查询从索 引的最左前列开始并且不跳过索引中的列。

    结论:过滤条件要使用索引必须按照索引建立时的顺序,依次满足,一旦跳过某个字段,索引后面的字段都无 法被使用。

    3. 不要在索引列上做任何计算

    ​ 不在索引列上做任何操作(计算、函数、(自动 or 手动)类型转换),会导致索引失效而转向全表扫描。

    3.1 在查询列上使用了函数

    EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE age=30;
    EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE LEFT(age,3)=30;
    
    • 1
    • 2

    在这里插入图片描述

    结论:等号左边无计算!

    3.2 在查询列上做了转换

    create index idx_name on emp(name);
    explain select sql_no_cache * from emp where name='30000';
    explain select sql_no_cache * from emp where name=30000;
    
    • 1
    • 2
    • 3

    字符串不加单引号,则会在 name 列上做一次转换!

    在这里插入图片描述

    结论:等号右边无转换!

    4. 索引列上不能有范围查询

    explain SELECT SQL_NO_CACHE * FROM emp WHERE emp.age=30 and deptid=5 AND emp.name = 'abcd';
    explain SELECT SQL_NO_CACHE * FROM emp WHERE emp.age=30 and deptid<=5 AND emp.name = 'abcd';
    
    • 1
    • 2

    在这里插入图片描述

    建议:将可能做范围查询的字段的索引顺序放在最后

    5. 尽量使用覆盖索引

    ​ 即查询列和索引列一直,不要写 select *!

    explain SELECT SQL_NO_CACHE * FROM emp WHERE emp.age=30 and deptId=4 and name='XamgXt';
    explain SELECT SQL_NO_CACHE age,deptId,name FROM emp WHERE emp.age=30 and deptId=4 and name='XamgXt';
    
    • 1
    • 2

    在这里插入图片描述

    6. 使用不等于(!= 或者<>)的时候

    ​ mysql 在使用不等于(!= 或者<>)时,有时会无法使用索引会导致全表扫描。

    在这里插入图片描述

    7. 字段的 is not null 和 is null

    在这里插入图片描述

    当字段允许为 Null 的条件下:

    在这里插入图片描述

    is not null 用不到索引,is null 可以用到索引。

    8. like 的前后模糊匹配

    在这里插入图片描述

    前缀不能出现模糊匹配!

    9. 减少使用 or

    在这里插入图片描述

    ​ 使用 union all 或者 union 来替代:

    在这里插入图片描述

    10. 练习

    假设 index(a,b,c);

    Where 语句索引是否被使用
    where a = 3Y,使用到 a
    where a = 3 and b = 5Y,使用到 a,b
    where a = 3 and b = 5 and c = 4Y,使用到 a,b,c
    where b = 3 或者 where b = 3 and c = 4 或者 where c = 4N
    where a = 3 and c = 5使用到 a, 但是 c 不可以,b 中间断了
    where a = 3 and b > 4 and c = 5使用到 a 和 b, c 不能用在范围之后,b 断了
    where a is null and b is not nullis null 支持索引 但是 is not null 不支持,所 以 a 可以使用索引,但是 b 不可以使用
    where a <> 3不能使用索引
    where abs(a) =3不能使用 索引
    where a = 3 and b like ‘kk%’ and c = 4Y,使用到 a,b,c
    where a = 3 and b like ‘%kk’ and c = 4Y,只用到 a
    where a = 3 and b like ‘%kk%’ and c = 4Y,只用到 a
    where a = 3 and b like ‘k%kk%’ and c = 4Y,使用到 a,b,c

    11. 口诀

    全职匹配我最爱,最左前缀要遵守;
    带头大哥不能死,中间兄弟不能断;
    索引列上少计算,范围之后全失效;
    LIKE 百分写最右,覆盖索引不写*;
    不等空值还有 OR,索引影响要注意;
    VAR 引号不可丢,SQL 优化有诀窍。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
  • 相关阅读:
    Chapter 4 k-近邻算法与朴素贝叶斯
    Spring源码:ApplicationContextAware和BeanFactoryAware理解BeanFactory和Aware
    引用——C++
    序列图怎么画,也就是顺序图
    Packet Tracer - 记录网络
    script 标签中的 async 和 defer 属性
    吸猫毛空气净化器哪个好?推荐除猫毛好的宠物空气净化器品牌
    算法题每日一练(一)
    注解与反射
    应急预案管理制度
  • 原文地址:https://blog.csdn.net/qq_36120342/article/details/126864491