zoukankan      html  css  js  c++  java
  • MySQL-覆盖索引总结笔记

    什么叫做覆盖索引?
    解释一: 就是select的数据列只用从索引中就能够取得,不必从数据表中读取,换句话说查询列要被所使用的索引覆盖。
    解释二: 索引是高效找到行的一个方法,当能通过检索索引就可以读取想要的数据,那就不需要再到数据表中读取行了。如果一个索引包含了(或覆盖了)满足查询语句中字段与条件的数据就叫做覆盖索引。
    解释三:是非聚集组合索引的一种形式,它包括在查询里的Select、Join和Where子句用到的所有列(即建立索引的字段正好是覆盖查询语句[select子句]与查询条件[Where子句]中所涉及的字段,也即,索引包含了查询正在查找的所有数据)。
    不是所有类型的索引都可以成为覆盖索引。覆盖索引必须要存储索引的列,而哈希索引、空间索引和全文索引等都不存储索引列的值,所以MySQL只能使用B-Tree索引做覆盖索引当发起一个被索引覆盖的查询(也叫作索引覆盖查询)时,在EXPLAIN的Extra列可以看到“Using index”的信息。
    注:遇到以下情况,执行计划不会选择覆盖查询。
    ①:select选择的字段中含有不在索引中的字段,即索引没有覆盖全部的列。
    ②:where条件中不能含有对索引进行like的操作。

    是否走索引,查询示例如下:

    CREATE TABLE `t_user` (
      `id` bigint(100) NOT NULL AUTO_INCREMENT,
      `password` varchar(255) DEFAULT NULL,
      `name` varchar(255) DEFAULT NULL,
      `phone` varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
      `age` int(11) DEFAULT NULL,
      `nick_name` varchar(255) DEFAULT NULL,
      `sex` int(255) DEFAULT NULL,
      `birthday` datetime DEFAULT NULL,
      `class_id` int(11) DEFAULT NULL COMMENT '班级id',
      PRIMARY KEY (`id`),
      KEY `index_phone` (`phone`) USING BTREE,
      KEY `index_birthday` (`birthday`) USING BTREE,
      KEY `index_name` (`name`,`age`) USING BTREE    # 联合索引
    ) ENGINE=InnoDB AUTO_INCREMENT=1588138958133 DEFAULT CHARSET=utf8;

     

    1:如上图所示:这次走的是覆盖索引,因为索引中包含了要查询的列字段,在联合索引中,或者是单个索引,所要查询的列的是索引的子集或者是相等,才能走覆盖索引,否则是要回表的(列id主键除外)。但是需要注意的是靠左匹配查询,这个是很重要的。在实际开发中,尽量使用覆盖索引,减少回表的操作。

    select age, name from t_user where age = '32'  --- 走索引 覆盖索引
    select age from t_user where age = '32'           ------- 走索引 覆盖索引
    
    select age, sex from t_user where age = '32'   ------- 不走索引 全表扫描
    select sex from t_user where age = '32'         ------- 不走索引 全表扫描
    
    select age, name from t_user where name = '32'   ------- 走索引 覆盖索引
    select sex from t_user where name = '32'    ------- 走索引 非覆盖索引
    
    select name,age, phone from t_user where name = '32'  ------- 走索引 非覆盖索引
    select sex from t_user where name = '32'      ------- 走索引 非覆盖索引
    
    select id from t_user where name = '32' ------- 走索引 覆盖索引
    select id from t_user where age = '32' ------- 走索引 覆盖索引

    总结:
    ①:在innodb存储引擎中,分为主键索引和辅助索引。只有在主键索引中,叶子节点存储的是数据记录(一行行的数据),且数据是按照主键从小到大的顺序进行排序。所以建议在排序的时候,排序字段最好也是创建索引,这样减少数据在内存中的排序时间。辅助索引叶子节点存储的是主键。
    ②:在innodb存储引擎中,表一定要创建主键索引,否则在等值查询中,会锁住全表,而不是锁住的某一行数据(行锁)。
    ③:在innodb存储引擎中,模糊查询like "XX%"不一定会走索引,因为考虑到列的离散型,列离散型越大,会走索引的可能性会比较大。比如像"aa1","aa2"..."aan",是不会走索引的。
    ④:在innodb存储引擎中,范围查询之后索引失效。比如index(name,age,phone), where name = 'guodong' and age > 20 and phone = '15317700182',这个时候只匹配name和age,phone是不会走索引的,原因也是列的离散型。
    ⑤:MySQL数据库服务器执行器优化的,比如index(name,age),where age = 12 and name = 'guodong',这个时候也是会走索引的,但是会有一个性能开销,所以还是最好是完全匹配。

  • 相关阅读:
    思维导图 第八章 项目质量管理
    思维导图 第七章 项目成本管理
    redis安装与配置
    思维导图 第六章 项目进度管理
    思维导图 第五章 项目范围管理
    Linux下用户-组权限配置
    意灵魔法馆首页的初步设计
    try catch自定义异常类的使用
    使用freemarker时,生成的html出现乱码
    乱码问题
  • 原文地址:https://www.cnblogs.com/jelly12345/p/13064781.html
Copyright © 2011-2022 走看看