• MySQL进阶-----SQL提示与覆盖索引


     目录

    前言

    一、SQL提示

    1.数据准备

    2. SQL的自我选择

    3.SQL提示

    二、覆盖索引


    前言

            MySQL进阶篇的索引部分基本上要结束了,这里就剩下SQL提示、覆盖索引、前缀索引以及单例联合索引的内容。那本期的话我们就先讲解SQL提示和覆盖索引先,剩下的内容就下一期作为完结篇讲解。

    一、SQL提示

    1.数据准备

    上一期链接MySQL进阶-----索引的语法与SQL性能分析-CSDN博客 ,下面这个表的内容均来自上一期的,可以通过上一期查看。

    目前tb_user表的数据情况如下:

    索引情况如下:

    把上述的 index_age 这个之前测试使用过的索引直接删除。

    drop index index_age on tb_user;

    2. SQL的自我选择

    这里我们通过案例去初步认识SQL提示(索引的使用)

    A. 执行SQL : explain select * from tb_user where profession = '软件工程';

    可以看出查询走了联合索引。
    B. 执行SQL,创建profession的单列索引:create index index_pro on
    tb_user(profession);
    C. 创建单列索引后,再次执行A中的SQL语句,查看执行计划,看看到底走哪个索引。
    测试结果,我们可以看到, possible_keys idx_user_pro_age_sta,idx_user_pro 这两个
    索引都可能用到,最终 MySQL 选择了 idx_user_pro_age_sta 索引。这是 MySQL 自动选择的结果。
    那么,我们能不能在查询的时候,自己来指定使用哪个索引呢? 答案是肯定的,此时就可以借助于MySQL的 SQL 提示来完成。 接下来,介绍一下 SQL 提示。

    3.SQL提示

    SQL 提示,是优化数据库的一个重要手段,简单来说,就是在 SQL 语句中加入一些人为的提示来达到优化操作的目的。
    (1) use index : 建议 MySQL 使用哪一个索引完成此次查询(仅仅是建议, mysql 内部还会再次进行评估)。
    explain select * from 表名字 use index(索引名字) where 条件;
    (2)ignore index : 忽略指定的索引。
    explain select * from 表名字 ignore index(索引名字) where 条件;
    (3)  force index : 强制使用索引。
    explain select * from 表名字 force index(索引名字) where 条件;

     示例演示:

    A. use index
    1. explain select * from tb_user use index(index_pro) where profession = '软件工
    2. 程';

    B. ignore index
    1. explain select * from tb_user ignore index(index_pro) where profession = '软件工
    2. 程';

    C. force index
    1. explain select * from tb_user force index(pro_age_sta) where profession =
    2. '软件工程';

    二、覆盖索引

    尽量使用覆盖索引,减少 select * 。 那么什么是覆盖索引呢? 覆盖索引是指 查询使用了索引,并
    且需要返回的列,在该索引中已经全部能够找到 。

     接下来,我们来看一组SQL的执行计划,看看执行计划的差别,然后再来具体做一个解析。

    1. explain select id, profession from tb_user where profession = '软件工程' and age =
    2. 31 and status = '0' ;
    3. explain select id,profession,age, status from tb_user where profession = '软件工程'
    4. and age = 31 and status = '0' ;
    5. explain select id,profession,age, status, name from tb_user where profession = '软
    6. 件工程' and age = 31 and status = '0' ;
    7. explain select * from tb_user where profession = '软件工程' and age = 31 and status
    8. = '0';

    执行结果如下: 

    从上述的执行计划我们可以看到,这四条 SQL 语句的执行计划前面所有的指标都是一样的,看不出来差异。但是此时,我们主要关注的是后面的Extra ,前面两天 SQL 的结果为 Using where; Using
    Index ; 而后面两条 SQL 的结果为 : Using index condition

    Extra

    含义

    Using where; Using

    Index

    查找使用了索引,但是需要的数据都在索引列中能找到,所以不需要回表查询数据

    Using index condition

    查找使用了索引,但是需要回表查询数据

    因为,在 tb_user 表中有一个联合索引 idx_user_pro_age_sta ,该索引关联了三个字段
    profession age status ,而这个索引也是一个二级索引,所以叶子节点下面挂的是这一行的主
    id 。 所以当我们查询返回的数据在 id profession age status 之中,则直接走二级索引
    直接返回数据了。 如果超出这个范围,就需要拿到主键 id ,再去扫描聚集索引,再获取额外的数
    了,这个过程就是回表。 而我们如果一直使用 select * 查询返回所有字段值,很容易就会造成回表
    查询(除非是根据主键查询,此时只会扫描聚集索引)。
    为了大家更清楚的理解,什么是覆盖索引,什么是回表查询,我们一起再来看下面的这组 SQL 的执行过程。
    A. 表结构及索引示意图:
    id 是主键,是一个聚集索引。 name 字段建立了普通索引,是一个二级索引(辅助索引)。
    B. 执行SQL : select * from tb_user where id = 2;
    根据 id 查询,直接走聚集索引查询,一次索引扫描,直接返回数据,性能高。
    C. 执行 SQL:selet id,name from tb_user where name = 'Arm';
    虽然是根据 name 字段查询,查询二级索引,但是由于查询返回在字段为 id name ,在 name 的二级索引中,这两个值都是可以直接获取到的,因为覆盖索引,所以不需要回表查询,性能高。
    D. 执行 SQL:selet id,name,gender from tb_user where name = 'Arm';
    由于在 name 的二级索引中,不包含 gender ,所以,需要两次索引扫描,也就是需要回表查询,性能相对较差一点。
    所以这下子理解了为什么通过主键id的搜索速度回更加快了吧!下面看一个思考题:
      思考题:
    一张表, 有四个字段(id, username, password, status), 由于数据量大, 需要对
    以下SQL语句进行优化, 该如何进行才是最优方案:
    select id,username,password from tb_user where username =
    'itcast';
    答案: 针对于 username, password建立联合索引, sql为: create index
    idx_user_name_pass on tb_user(username,password);
    这样可以避免上述的SQL语句,在查询的过程中,出现回表查询。  

     以上就是本期的全部内容了,加纳!

    分享一张壁纸:

  • 相关阅读:
    LDblock绘制连锁不平衡和单体型图
    GBase 8c V3.0.0数据类型——密态等值函数
    如何使用Java创建数据透视表并导出为PDF
    手把手带你学python—牛客网python基础 乘法与幂运算
    QT 实现 TCP 客户端服务器代码
    [极客大挑战 2019]Http
    关于javaFx tableView组件绑定Map数据
    JavaWeb JavaScript
    了解JVM中的Server和Client参数
    【ES6】学习笔记:解构赋值
  • 原文地址:https://blog.csdn.net/m0_73633088/article/details/137275531