精华内容
下载资源
问答
  • Mysql覆盖索引详解

    2020-12-16 10:53:17
    如果索引包含所有满足查询需要的数据的索引成为覆盖索引(Covering Index),也就是平时所说的不需要回表操作 判断标准 使用explain,可以通过输出的extra列来判断,对于一个索引覆盖查询,显示为using index,MySQL...
  • MongoDB 覆盖索引查询

    2020-12-16 16:39:02
    MongoDB 覆盖索引查询 官方的MongoDB的文档中说明,覆盖查询是以下的查询: 所有的查询字段是索引的一部分 所有的查询返回字段在同一个索引中 由于所有出现在查询中的字段是索引的一部分, MongoDB 无需在整个数据...
  • 主要介绍了MySQL 的覆盖索引与回表的使用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 在了解覆盖索引之前我们先大概了解一下什么是聚集索引(主键索引)和辅助索引(二级索引) 聚集索引(主键索引): 聚集索引就是按照每张表的主键构造一颗B+树,同时叶子节点中存放的即为整张表的记录数据。 聚集索引的...
  • 如果一个索引包含(或覆盖)所有需要查询的字段的值,称为‘覆盖索引‘。 覆盖索引是一种非常强大的工具,能大大提高查询性能,只需要读取索引而不需要读取数据,有以下优点: 1、索引项通常比记录要小,所以MySQL访问...
  • 文档介绍了MogoDB数据库索引与覆盖索引查询, MongoDB 引用有两种:手动引用(Manual References)和 DBRefs。
  • 覆盖索引

    2021-03-04 22:09:33
    覆盖索引 1、当发起一个被索引覆盖的查询时,在explain的extra列可以看到using index的信息,此时就使用了覆盖索引 mysql> explain select store_id,film_id from inventory\G *************************** 1. ...

    覆盖索引

    基本介绍

    1、如果一个索引包含所有需要查询的字段的值,我们称之为覆盖索引
    2、不是所有类型的索引都可以称为覆盖索引,覆盖索引必须要存储索引列的值
    3、不同的存储实现覆盖索引的方式不同,不是所有的引擎都支持覆盖索引,memory不支持覆盖索引

    优势

    1、索引条目通常远小于数据行大小,如果只需要读取索引,那么mysql就会极大的较少数据访问量
    2、因为索引是按照列值顺序存储的,所以对于IO密集型的范围查询会比随机从磁盘读取每一行数据的IO要少的多
    3、一些存储引擎如MYISAM在内存中只缓存索引,数据则依赖于操作系统来缓存,因此要访问数据需要一次系统调用,这可能会导致严重的性能问题

    案例

    1、当发起一个被索引覆盖的查询时,在explain的extra列可以看到using index的信息,此时就使用了覆盖索引

    mysql> explain select store_id,film_id from inventory\G
    *************************** 1. row ***************************
               id: 1
      select_type: SIMPLE
            table: inventory
       partitions: NULL
             type: index
    possible_keys: NULL
              key: idx_store_id_film_id
          key_len: 3
              ref: NULL
             rows: 4581
         filtered: 100.00
            Extra: Using index
    1 row in set, 1 warning (0.01 sec)
    
    

    2、在大多数存储引擎中,覆盖索引只能覆盖那些只访问索引中部分列的查询。不过,可以进一步的进行优化,可以使用innodb的二级索引来覆盖查询。

    例如:actor使用innodb存储引擎,并在last_name字段又二级索引,虽然该索引的列不包括主键actor_id,但也能够用于对actor_id做覆盖查询

    mysql> explain select actor_id,last_name from actor where last_name='HOPPER'\G
    *************************** 1. row ***************************
               id: 1
      select_type: SIMPLE
            table: actor
       partitions: NULL
             type: ref
    possible_keys: idx_actor_last_name
              key: idx_actor_last_name
          key_len: 137
              ref: const
             rows: 2
         filtered: 100.00
            Extra: Using index
    1 row in set, 1 warning (0.00 sec)
    
    
    展开全文
  • Mysql 覆盖索引及其使用注意事项

    千次阅读 2019-08-04 03:23:33
    一,什么叫覆盖索引 网上对覆盖索引的定义有如下三种: 解释一: 就是select的数据列只用从索引中就能够取得,不必从数据表中读取,换句话说查询列要被所使用的索引覆盖。 解释二: 索引是高效找到行的一个方法,...

    一,什么叫覆盖索引

    网上对覆盖索引的定义有如下三种:

    • 解释一: 就是select的数据列只用从索引中就能够取得,不必从数据表中读取,换句话说查询列要被所使用的索引覆盖。
    • 解释二: 索引是高效找到行的一个方法,当能通过检索索引就可以读取想要的数据,那就不需要再到数据表中读取行了。如果一个索引包含了(或覆盖了)满足查询语句中字段与条件的数据就叫做覆盖索引。
    • 解释三:是非聚集组合索引的一种形式,它包括在查询里的Select、Join和Where子句用到的所有列(即建立索引的字段正好是覆盖查询语句[select子句]与查询条件[Where子句]中所涉及的字段,也即,索引包含了查询正在查找的所有数据)。

    个人认为,覆盖索引,通俗些说,就是能在某次查询中能同时覆盖到所有的查询结果和查询条件的索引。这里澄清下,覆盖索引首先是一个索引;覆盖索引覆盖的是什么呢?覆盖的是所有查要读取的所有的列,同时也覆盖所有的查询条件。

    另外有一个争论的问题:一个索引是否是覆盖索引,是针对某次查询而言的?还是一个索引定义之后,它是否是覆盖索引也就确定了?针对这个问题,在几个群里讨论了之后,没有得出一个统一的结论,感觉每一种解释都不和先前网上的一些定义冲突,都能说的过去。本篇更偏向于第一种观点:一个索引是否是覆盖索引,它定义好之后是无法确定是否是覆盖索引的,只有具体到某次查询,才知道这个索引是否同时覆盖了查询结果的列和查询条件,从而做出是否是覆盖索引的判定,所以一个索引是否是覆盖索引是针对某次查询而言的。

    在Explain的时候,输出的Extra信息中如果有“Using Index”,就表示这条查询使用了覆盖索引。

    使用了覆盖索引的查询也称为索引覆盖查询。

    二,覆盖索引的优点:

      覆盖索引是非常有用的工具,能够极大的提高性能。如果SQL查询只需要扫描索引而无需回表,会带来多少好处:

    • 索引条目通常远小于数据行大小,所以如果只需读取索引,那mysql就会极大的减少数据访问量。这对缓存的负载非常重要,因为这种情况下响应时间大部分花费在数据拷贝上。覆盖索引对于I/O密集型的应用也很有帮助,因为索引比数据更小,更容易全部放入内存中。
    • 由于InnoDB的聚簇索引,覆盖索引对InnoDB特别有用。InnoDB的二级索引在叶子节点中保存了行的主键值,所以如果二级主键能够覆盖查询,则可以避免对主键索引的二次查询。减少IO,提高效率。
    • 因为索引是按照列值顺序存储的,所以对于I/O密集型的范围查询会比随机从磁盘读取每一行数据的I/O要少的多。对于某些存储引擎,例如MyISAM,甚至可以通过optimize命令使得索引完全顺序排列,这让简单的范围查询能使用完全顺序的索引访问。

    三,覆盖索引的适用范围

    不是所有类型的索引都可以成为覆盖索引。覆盖索引必须要存储索引的列值(因为SQL查询结果和查询条件的都涉及到具体的值,而覆盖索引需要覆盖查询结果和查询条件),而哈希索引、空间索引和全文索引等都不存储索引列的值,所以MySQL只能使用B-Tree或B+Tree索引做覆盖索引。另外,不同的存储引擎实现覆盖索引的方式也不同,而且不是所有的引擎都支持覆盖索引。

    四, 覆盖索引优化示例

    有这么一张表:

    CREATE TABLE `user_group` ( 
      `id` int(11) NOT NULL auto_increment, 
      `uid` int(11) NOT NULL, 
      `group_id` int(11) NOT NULL, 
      PRIMARY KEY  (`id`), 
      KEY `uid` (`uid`), 
      KEY `group_id` (`group_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=750366 DEFAULT CHARSET=utf8

    看AUTO_INCREMENT就知道数据并不多,75万条。然后是一条简单的查询:

    SELECT SQL_NO_CACHE uid FROM user_group WHERE group_id = 245;

     该条语句查询需要0.15s左右。但是真实的业务需求比这个复杂,查询需要2.2s.,最终定位到问题症结是在这条SQL。

    Explain的结果是:

    +----+-------------+------------+------+---------------+----------+---------+-------+------+-------+ 
    | id | select_type | table      | type | possible_keys | key      | key_len | ref   | rows | Extra | 
    +----+-------------+------------+------+---------------+----------+---------+-------+------+-------+ 
    |  1 | SIMPLE      | user_group | ref  | group_id      | group_id | 4       | const | 5544 |       | 
    +----+-------------+------------+------+---------------+----------+---------+-------+------+-------+
    

    看上去已经用上索引了,好像已经没有办法优化了。实际上不然,当我们再创建一个如下联合索引时(注意,创建该索引后要把原来的group_id索引删除,因为按照定义的先后顺序,where条件会优先使用group_id索引而不是联系索引查询):

    ALTER TABLE user_group ADD INDEX group_id_uid (group_id, uid);

    然后,不可思议的事情发生了……这句SQL查询的性能发生了巨大的提升,居然已经可以跑到0.00s左右了。经过优化的SQL再结合真实的业务需求,也从之前2.2s下降到0.05s。

    再Explain一次:

    +----+-------------+------------+------+-----------------------+--------------+---------+-------+------+-------------+ 
    | id | select_type | table      | type | possible_keys         | key          | key_len | ref   | rows | Extra       | 
    +----+-------------+------------+------+-----------------------+--------------+---------+-------+------+-------------+ 
    |  1 | SIMPLE      | user_group | ref  | group_id,group_id_uid | group_id_uid | 4       | const | 5378 | Using index | 
    +----+-------------+------------+------+-----------------------+--------------+---------+-------+------+-------------+

    可以看到使用了覆盖索引,MySQL只需要通过索引就可以返回查询所需要的数据,而不必在查到索引之后再去查询数据。

    五,使用覆盖索引注意事项

    1,当只查询表的id字段时,是索引覆盖查询,如下为索引覆盖查询

    SELECT SQL_NO_CACHE id FROM user_group;

    2,当where和select查询的列分别创建单独的索引时,不是索引覆盖查询

    如id为主键,为uid和group_id分别创建索引时,则如下不是索引覆盖查询:

    SELECT SQL_NO_CACHE uid FROM user_group WHERE group_id = 123;

    因为该查询是通过group_id索引获取到主键值,通过主键在数据表中获取数据(回表查询),再查询其中uid的值

    3,当无where时,select查询的列为主键和另一个索引时,是索引覆盖查询

    如id为主键,uid为索引,则如下查询是索引覆盖查询(其中id和uid顺序可以改变):

    SELECT SQL_NO_CACHE id, uid FROM user_group;

    因为通过uid索引,可以直接获取到uid和id的值,而无需回表查询。

    当如上查询有where时,则where条件必须是另一个非主键索引,才是索引覆盖查询

    4,select查询的列为两个及两个以上单独加了索引的字段时(或包含非索引字段),不是索引覆盖查询

    如id为主键,分别为uid和group_id创建索引,如下查询不是索引覆盖查询

    SELECT SQL_NO_CACHE uid,group_id FROM user_group;

    因为此时不会使用到索引,而是会做全表查询。

    而explain SELECT SQL_NO_CACHE uid,group_id FROM user_group where uid = 2 and group_id = 123;会同时使用两个索引,但也不是索引覆盖查询。

    5,如果select查询的列只要都同时属于同一个组合索引中的全部或部分列时,都是索引覆盖查询

    5.1 如id为主键,存在组合索引group_id_uid(group_id, uid)时,如下查询都是索引覆盖查询:

    SELECT SQL_NO_CACHE group_id FROM user_group;
    SELECT SQL_NO_CACHE uid FROM user_group;
    SELECT SQL_NO_CACHE uid,group_id FROM user_group;

      原因:MySQL查询优化器会在执行查询前判断是否有一个索引能进行覆盖,如果存在的话,则会使用该索引进行查询。

    5.2 当上述带上where条件查询时,如果where后面要是包含除了该联合索引以外的字段(或不符合索引的前缀匹配原则)时,都不是索引覆盖查询(联合索引和主键同时作为查询条件也不行)。

    5.3 如果where后面的查询条件都为联合索引中的字段且是符合前缀匹配原则时,是索引覆盖查询,如下是索引覆盖查询:

    SELECT SQL_NO_CACHE id, group_id FROM user_group where uid = 2 and group_id = 123
    

    6, where后面的查询条件包含非索引字段 或两个及两个以上的所属不同索引字段 时,都不是索引覆盖查询。

    6.1 如group_id为联合索引的前缀,name为一个单独的索引,则如下不是索引覆盖查询

    SELECT SQL_NO_CACHE group_id, name FROM user_group where group_id = 123 and name = "test" ;
    

    6.2 分别为uid和group_id创建独立索引, 即使只查询其中一个索引字段的值或id的值,也不是索引覆盖查询。

    SELECT SQL_NO_CACHE uid FROM user_group where uid = 2 and group_id = 123;

    7,where条件中包含like的操作可能也是索引覆盖查询

    如果id为主键,name为索引

    7.1 执行如下,关键词前缀匹配查询,只范围查询具有对应前缀的数据值

    explain SELECT name FROM `user_group` where name like "test%";

    显示结果为 Using where; Using index:

    +----+-------------+------------+------------+-------+---------------+------+---------+------+------+----------+--------------------------+
    | id | select_type | table      | partitions | type  | possible_keys | key  | key_len | ref  | rows | filtered | Extra                    |
    +----+-------------+------------+------------+-------+---------------+------+---------+------+------+----------+--------------------------+
    |  1 | SIMPLE      | user_group | NULL       | range | name          | name | 768     | NULL |    1 |   100.00 | Using where; Using index |
    +----+-------------+------------+------------+-------+---------------+------+---------+------+------+----------+--------------------------+

    7.2 执行如下,关键词非前缀匹配查询,查询所有的name索引值

    explain SELECT name FROM `user_group` where name like "%test";
    # 或
    explain SELECT name FROM `user_group` where name like "%test%";

    显示结果为 Using where; Using index:

    +----+-------------+------------+------------+-------+---------------+------+---------+------+------+----------+--------------------------+
    | id | select_type | table      | partitions | type  | possible_keys | key  | key_len | ref  | rows | filtered | Extra                    |
    +----+-------------+------------+------------+-------+---------------+------+---------+------+------+----------+--------------------------+
    |  1 | SIMPLE      | user_group | NULL       | index | NULL          | name | 768     | NULL |    3 |    33.33 | Using where; Using index |
    +----+-------------+------------+------------+-------+---------------+------+---------+------+------+----------+--------------------------+

    则以上都是索引覆盖查询,但是无需回表查询。只是如果查询的列中包含其它非索引的列,可能需要回表查询,则不是索引覆盖查询。

    注:以上都是Mysql 5.7.14版本:Server version: 5.7.14 MySQL Community Server (GPL)

    参考:

    https://www.cnblogs.com/happyflyingpig/p/7662881.html

    https://www.cnblogs.com/zl0372/articles/mysql_32.html

    展开全文
  • 如果你不知道什么是覆盖索引,那么SQL性能优化便无从谈起! 什么是覆盖索引?如何利用索引进行SQL语句优化? 表结构 150多万的数据,这么一个简单的语句: 慢查询日志里居然很多用了1秒的,Explain的结果是: 从...

    在这里插入图片描述


    1. 什么是索引?

    索引(在 MySQL 中也叫“键key”)是存储引擎快速找到记录的一种数据结构,通俗来说类似书本的目录,这个比方虽然被用的最多但是也是最恰如其当的,在查询书本中的某个知识点不借助目录的情况下,往往都找的够呛,那么索引相较于数据库的重要性也可见一斑。

    2. 索引的有哪些种类?

    索引的种类这里只罗列出InnoDB支持的索引:主键索引(PRIMARY),普通索引(INDEX),唯一索引(UNIQUE),组合索引,总体划分为两类,主键索引也被称为聚簇索引(clustered index),其余都称呼为非主键索引也被称为二级索引(secondary index)。

    3. InnoDB的不同的索引组织结构是怎样的呢?

    众所周知在InnoDB引用的是B+树索引模型,这里对B+树结构暂时不做过多阐述,很多文章都有描述,在第二问中我们对索引的种类划分为两大类主键索引和非主键索引,那么问题就在于比较两种索引的区别了,我们这里建立一张学生表,其中包含字段id设置主键索引、name设置普通索引、age(无处理),并向数据库中插入4条数据:(“小赵”, 10)(“小王”, 11)(“小李”, 12)(“小陈”, 13)

    CREATE TABLE `student` (
      `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增主键',
      `name` varchar(32) COLLATE utf8_bin NOT NULL COMMENT '名称',
      `age` int(3) unsigned NOT NULL DEFAULT '1' COMMENT '年龄',
      PRIMARY KEY (`id`),
      KEY `I_name` (`name`)
    ) ENGINE=InnoDB;
    
    INSERT INTO student (name, age) VALUES("小赵", 10),("小王", 11),("小李", 12),("小陈", 13);
    

    复制代码这里我们设置了主键为自增,那么此时数据库里数据为

    每一个索引在 InnoDB 里面对应一棵B+树,那么此时就存着两棵B+树。

    img

    可以发现区别在与叶子节点中,主键索引存储了整行数据,而非主键索引中存储的值为主键id, 在我们执行如下sql后

    SELECT age FROM student WHERE name = '小李';
    

    复制代码流程为:

    1. 在name索引树上找到名称为小李的节点 id为03
    2. 从id索引树上找到id为03的节点 获取所有数据
    3. 从数据中获取字段命为age的值返回 12

    在流程中从非主键索引树搜索回到主键索引树搜索的过程称为:回表,在本次查询中因为查询结果只存在主键索引树中,我们必须回表才能查询到结果,那么如何优化这个过程呢?引入正文覆盖索引

    4. 什么是覆盖索引?

    覆盖索引(covering index ,或称为索引覆盖)即从非主键索引中就能查到的记录,而不需要查询主键索引中的记录,避免了回表的产生减少了树的搜索次数,显著提升性能。

    5. 如何使用是覆盖索引?

    之前我们已经建立了表student,那么现在出现的业务需求中要求根据名称获取学生的年龄,并且该搜索场景非常频繁,那么先在我们删除掉之前以字段name建立的普通索引,以name和age两个字段建立联合索引,sql命令与建立后的索引树结构如下

    ALTER TABLE student DROP INDEX I_name;
    ALTER TABLE student ADD INDEX I_name_age(name, age);
    

    复制代码
    那在我们再次执行如下sql后

    SELECT age FROM student WHERE name = '小李';
    

    复制代码流程为:

    1. 在name,age联合索引树上找到名称为小李的节
    2. 此时节点索引里包含信息age 直接返回 12

    6. 如何确定数据库成功使用了覆盖索引呢?

    当发起一个索引覆盖查询时,在explain的extra列可以看到using index的信息

    这里我们很清楚的看到Extra中Using index表明我们成功使用了覆盖索引

    总结:覆盖索引避免了回表现象的产生,从而减少树的搜索次数,显著提升查询性能,所以使用覆盖索引是性能优化的一种手段


    真实场景

    表结构

    img

    150多万的数据,这么一个简单的语句:

    img

    慢查询日志里居然很多用了1秒的,Explain的结果是:

    img

    从Explain的结果可以看出,查询已经使用了索引,但为什么还这么慢?

    分析:首先,该语句ORDER BY 使用了Using filesort文件排序,查询效率低;其次,查询字段不在索引上,没有使用覆盖索引,需要通过索引回表查询;也有数据分布的原因。

    知道了原因,那么问题就好解决了。

    解决方案:由于只需查询uid字段,添加一个联合索引便可以避免回表和文件排序,利用覆盖索引提升查询速度,同时利用索引完成排序。

    img

    覆盖索引:SQL只需要通过索引就可以返回查询所需要的数据,而不必通过二级索引查到主键之后再去查询数据。

    我们再Explain看一次:

    img

    Extra信息已经有’Using Index’,表示已经使用了覆盖索引。经过索引优化之后,线上的查询基本不超过0.001秒。

    总结:

    当一条查询语句符合覆盖索引条件时,sql只需要通过索引就可以返回查询所需要的数据,这样避免了查到索引后再返回表操作,减少I/O提高效率。
    使用覆盖索引Innodb比MyISAM效果更好----InnoDB使用聚集索引组织数据,如果二级索引中包含查询所需的数据,就不再需要在聚集索引中查找了

    注:遇到以下情况,执行计划不会选择覆盖查询
    1.select选择的字段中含有不在索引中的字段 ,即索引没有覆盖全部的列。
    2.where条件中不能含有对索引进行like的操作。

    展开全文
  • mysql 性能优化 - 覆盖索引前言正文mysql 索引数据结构主键索引二级索引联合索引Explain 简单描述覆盖索引 前言 刚毕业时,公司大佬曾经说过:像关系型数据库这类东西,说不定哪天就被淘汰了,你们没必要花费太多...

    前言

    刚毕业时,公司大佬曾经说过:像关系型数据库这类东西,说不定哪天就被淘汰了,你们没必要花费太多精力在上面,应该着重于 非关系型数据库 ,像 mysql 之类的,会用就好了,不用太深入研究!!

    现在我想说一句,老贼误我!!!
    在这里插入图片描述
    且不说 拥有靠谱的DBA的公司本身就少,而且作为公司的部门,想要用到DBA的资源也是不容易的,所以大部分的sql优化,还是要会的!!这是基础!!!

    就比如当下,需要对数据库进行调优,我的第一个念头就是建立索引。然后,就没有然后了…

    要先了解数据库底层的存储结构是什么样的,才能根据业务建立起相对可行的索引,才能调整查询语句,达到性能提升的地步,不然建立索引就是瞎建立,就是个愣头青!!(说的就是我)
    在这里插入图片描述

    本文主要讲述一下 覆盖索引 ,为什么要讲它??因为我竟然从来没听过这是个啥!!!结果被学弟好好鄙视了一番!!!
    在这里插入图片描述

    正文

    mysql 索引数据结构

    先说说啥是索引:索引是帮助 MySQL 高效获取数据的 排好序 数据结构

    这边为啥要突出排好序??
    因为当是有序时,搜索的速度会快于乱序的 数据结构,正因为如此,阿里巴巴的开发手册中,才推荐不要再用 uuid ,而是用雪花算法作为主键索引。

    MySql 的索引数据结构用的 B+Tree :简要说明:ps(这次画图用 processOn ,应该会比以往好看一点了)

    在这里插入图片描述

    特性:

    • 叶子节点包含所有的索引字段(蓝色区域)
    • 非叶子节点(除了黄色区域)不存储data,只存储索引,可以存放更多的索引
    • 叶子结点用指针连接,提高区间访问的性能(索引有序,加快访问,所以推荐主键雪花算法)
    • 所有的data存储在叶子节点上

    现在市面上使用的存储引擎绝大部分是 InnoDb 而不是 MYISAM ,最大的原因是 InnoDb 的索引文件和数据文件是聚集的,而 MYISAM 的索引文件和数据文件是非聚集的。所以以下都是以 InnoDb 为例。

    主键索引

    在这里插入图片描述

    主键索引如图:索引为主键值(蓝色),叶子阶段存储所有数据(黄色部分)。

    二级索引

    在这里插入图片描述

    二级索引如图:索引是name(蓝色部分),而此处的叶子节点(黄色部分)并不会存储所有数据,仅仅是存储了主键的id,最终查询是会查询到此处叶子节点的id在进行回表查询。(非聚集索引)

    联合索引

    ps(此处举例非主键,所以值是主键id,而若是主键联合索引,则和上面一致,值是数据)

    在这里插入图片描述
    这里有一个 左列原则(最左前缀原则)

    建立的联合索引是 name,age ,所以 索引的建立先以name为排序,若name相同再比较 age 为排序。

    所以当查询的时候直接以条件为name,会走索引。直接以条件为age,则不走索引。

    Explain 简单描述

    想对于sql进行优化,Explain 绝对是要掌握的知识,不过本文并不以这个为主要核心,所以只是稍微描述一下。

    举例:
    只需要在查询语句上,加上 Explain 即可
    在这里插入图片描述
    查询结果如下:
    在这里插入图片描述

    • id 列:id列的编号是 select 的序列号,有几个 select 就有几个id,并且id的顺序是按 select 出现的顺序增长的。id列越大执行优先级越高,id相同则从上往下执行,id为NULL最后执行。(当执行关联查询此处就会有多个)。

    • select_type:表示对应行是简单还是复杂的查询。
      simple:简单查询。查询不包含子查询和union
      primary:复杂查询中最外层的 select
      subquery:包含在 select 中的子查询(不在 from 子句中)
      derived:包含在 from 子句中的子查询。MySQL会将结果存放在一个临时表中,也称为派生表(derived的英文含义)。
      union:在 union 中的第二个和随后的 select。

    • table:表示 explain 的一行正在访问哪个表。

    • type:关联类型或访问类型,即MySQL决定如何查找表中的行,查找数据行记录的大概范围。

    • possible_keys:这一列显示查询可能使用哪些索引来查找。explain 时可能出现 possible_keys 有列,而 key 显示 NULL 的情况,这种情况是因为表中数据不多,mysql认为索引对此查询帮助不大,选择了全表查询。

    • key:这一列显示mysql实际采用哪个索引来优化对该表的访问。

    • key_len:这一列显示了mysql在索引里使用的字节数,通过这个值可以算出具体使用了索引中的哪些列。

    • ref:这一列显示了在key列记录的索引中,表查找值所用到的列或常量,常见的有:const(常量),字段名

    • rows:这一列是mysql估计要读取并检测的行数,注意这个不是结果集里的行数。

    • Extra:这一列展示的是额外信息(此处值非常多,仅仅举例覆盖索引)。Using index。

    覆盖索引

    前面说了那么多,终于轮到正主登场~(若是对前面知识一无所知,怎么可能建的好索引呢??)

    在这里插入图片描述
    覆盖索引定义:mysql执行计划explain结果里的key有使用索引,如果select后面查询的字段都可以从这个索引的树中获取,这种情况一般可以说是用到了覆盖索引,extra里一般都有using index;覆盖索引一般针对的是辅助索引,整个查询结果只通过辅助索引就能拿到结果,不需要通过辅助索引树找到主键,再通过主键去主键索引树里获取其它字段值。

    举例说明:
    现在有一张表,我建立了联合索引 在这里插入图片描述
    此时我对它进行查询:
    在这里插入图片描述

    此处发现 key 为null ,有建立索引,为什么它不走呢。也满足了最左前缀原则!! 这是因为,mysql底层 会再次进行优化,它判断不走索引会比走索引快,所以 possible_keys 有值,但是最后没走。具体分析可以使用 trace

    而 Extra 并不是 Using index,所以没有使用 覆盖索引。

    此时,更改查询条件
    在这里插入图片描述
    查询索引字段,发现它走索引了!走索引了!
    在这里插入图片描述
    这是因为,当查询的时候,他根据联合索引查到了值,但是由于搜索的字段是索引本身字段,所以值可以在索引上拿到,并不需要去回表查询,因此,效率杠杠的高!!!

    展开全文
  • 因为无法同时把数据行存在两个不同的地方,所以一个表只能有一个聚簇索引(覆盖索引可以模拟多个聚簇索引的情况) 索引的建立 一个表有且只有一个聚簇索引; InnoDB一般是通过主键建立聚簇索引; 如果没有定义主键...
  • 本文介绍 PostgreSQL 11 版本中新增的覆盖索引(covering index) 特性,即 CREATE INDEX ... INCLUDE 语句。 有时候,索引不仅仅能够用于定位表中的数据。某些查询可能只需要访问索引的数据,就能够获取所需要的...
  • 简单易懂的MySQL覆盖索引、前缀索引、索引下推

    千次阅读 多人点赞 2021-07-17 20:08:04
    文章目录前言聚集索引/非聚集索引 前言 聚集索引/非聚集索引
  • 如果一个索引包含(或覆盖)所有需要查询的字段的值,称为‘覆盖索引’。即只需扫描索引而无须回表。 只扫描索引而无需回表的优点: 1.索引条目通常远小于数据行大小,只需要读取索引,则mysql会极大地减少数据访问...
  • 文章目录前言round1:覆盖索引round2:最左前缀原则 前言 在文章开始前,小编提出几个问题,读者可以思考一下如何回答。如果对于以下的问题,回答的模棱两可甚至根本不了解,我想这篇文章应该会合你的口味。 查询...
  • MySQL之高效覆盖索引

    2016-03-15 10:47:48
    MySQL之高效覆盖索引
  • 聚集索引,非聚集索引,覆盖索引 原理

    万次阅读 多人点赞 2018-08-28 11:37:34
    「数据库」和「数据库索引」这两个东西是在服务器端开发领域应用最为广泛的两个概念,熟练使用数据库和数据库索引是开发人员在行业内生存的必备技能 使用索引很简单,只要能写创建表的语句,就肯定能写创建索引的...
  • MySQL-索引-覆盖索引

    2019-09-21 11:05:46
    覆盖索引 1.什么是覆盖索引? 概念:查询语句中所需要的列在索引中,这样查询结果在索引的数据结构中查找即可拿到结果。 附加网友解释: 解释一: 就是select的数据列从索引中就能够获取,不必从数据表中再次读取...
  • 文章目录分布式NoSQL列存储数据库Hbase(七)知识点02:课程目标知识点03:Phoenix二级索引设计知识点04:二级索引:全局索引设计知识点05:二级索引:全局索引实现知识点06:二级索引:覆盖索引设计知识点07:二级...
  • 前缀索引和覆盖索引

    千次阅读 2018-08-07 15:38:08
    索引的字符串列很大时,创建的索引也就变得很大,为了减小索引体积,提高索引的扫描速度,就用索引的前部分字串索引,这样索引占用的空间就会大大减少,并且索引的选择性也不会降低很多。而且是对BLOB和TEXT列进行...
  • MySQL覆盖索引(Covering Index)

    千次阅读 2017-08-29 11:25:57
    MySQL覆盖索引(Covering Index) mysql高效索引之覆盖索引 ...
  • The article summary1 什么是回表查询1.1 mysql的存储引擎1.2 InnoDb存储引擎1.3 聚集索引和普通索引的区别2 什么是覆盖索引3 怎样实现覆盖索引4 哪些场景下可以使用索引覆盖来优化sql 1 什么是回表查询 前提:本次...
  • 覆盖索引有何用?

    千次阅读 2018-10-06 19:23:38
    如果索引的叶子节点包含了要查询的数据,那么就不用回表查询了,也就是说这种索引包含(亦称覆盖)所有需要查询的字段的值,我们称这种索引为覆盖索引。 注:引入数据表t_user,插入约1千万条记录,用作下文例子使用...
  • 3、覆盖索引 优点 应用覆盖索引 1、聚簇索引 一篇聚簇索引数据结构的文章:聚簇索引数据结构 聚簇索引并不是一种单独的索引类型,而是一种数据存储方式。InnoDB存储引擎的聚簇索引的背后数据结构就是 B-Tree...
  • 在《面试官:为啥加了索引查询会变快?》一文中,我们介绍了索引的数据结构,正是因为索引使用了B+树,才使得查询变快。说白了,索引的原理就是减少查询的次数、减少磁盘IO,达到快速查找所需数据的目的 我们一起来...
  • 一、覆盖索引 1.1 概念 索引是高效找到行的一个方法,当能通过检索索引就可以读取想要的数据,那就不需要再到数据表中读取行了。如果一个索引包含了(或覆盖了)满足查询语句中字段与条件的数据就叫做覆盖索引。 1.2...
  • SQL server 覆盖索引和复合索引的区别

    千次阅读 2019-07-22 10:55:03
    覆盖索引 所谓的包含列就是包含在非聚集索引中,并且不是索引列中的列。或者说的更通俗一点就是:把一些底层数据表的数据列包含在非聚集索引的索引页中,而这些数据列又不是索引列,那么这些列就是包含列。同时,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 272,914
精华内容 109,165
关键字:

覆盖索引