zoukankan      html  css  js  c++  java
  • 回表和索引覆盖介绍

    本章中我们主要理解以下几个问题:

    (1)基于主键索引和普通索引的查询有什么区别?

    (2)怎么理解回表?

    (3)怎么理解索引覆盖?

    索引结构示例分析

    在InnoDB中,表都是根据主键顺序以索引的形式存放的,这种存储方式的表称为索引组织表。 InnoDB使用了B+树索引模型,所以数据都是存储在B+树中的。 每一个索引在InnoDB里面对应一棵B+树

    假设,我们有一个主键列为ID的表,表中有字段k,并且在k上有索引。

    这个表的建表语句是:

     表中R1~R5的(id,k)值分别为(100,1,’aa’)、(200,2,’bb’)、(300,3,’cc’)、(500,5,’dd’)和(600,6,’ee’),两棵树的示例示意图如下。

    从图中不难看出,根据叶子节点的内容,索引类型分为主键索引和非主键索引

    主键索引的叶子节点存的是整行数据。在InnoDB里,主键索引也被称为聚簇索引(clustered index)。

    非主键索引的叶子节点内容是主键的值。在InnoDB里,非主键索引也被称为二级索引 (secondary index)。

    根据上面的索引结构说明,我们来讨论一个问题:

    基于主键索引和普通索引的查询有什么区别?怎么理解回表? 

    (1)如果语句是select * from T where ID=500,即主键查询方式,则只需要搜索ID这棵B+树;

    (2)如果语句是select * from T where k=5,即普通索引查询方式,则需要先搜索k索引树,得到ID 的值为500,再到ID索引树搜索一次。这个过程称为回表

    也就是说,基于非主键索引的查询需要多扫描一棵索引树。因此,我们在应用中应该尽量使用主键查询

    怎么理解覆盖索引?

    当我们执行select * from T where k=5,由于查询结果所需要的数据只在主键索引上有,所以不得不回表。那么,有没有可能经过索引优化,避免回表过程呢?     

    如果执行的语句是select ID fromTwhere k =5,这时只需要查ID的值,而ID的值已经在k索引树上了,因此可以直接提供查询结果,不需要回表。也就是说,在这个查询里面, 索引k已经“覆盖了”我们的查询需求,我们称为覆盖索引

    由于覆盖索引可以减少树的搜索次数,显著提升查询性能,所以使用覆盖索引是一个常用 的性能优化手段

    面试中简要回答

    平时在写SQL时应该尽量使用主键查询和覆盖索引,可以减少树的搜索次数也就是避免回表,从而提升查询性能。具体原理如下:

    每一个索引在InnoDB里面对应一棵B+树。主键索引的叶子节点存的是整行数据,非主键索引的叶子节点内容是主键的值。好比我们有一个以id为主键的表,表中有个加了普通索引的字段K。

    (1) 当我们查询select * from T where k=5时,需要先搜索k索引树,拿到主键的值后再到ID主键索引树上搜索一次。这个过程称为回表

    (2)如果执行的语句是select ID from T where k =5,这时只需要查ID的值,而ID的值已经在k索引树上了,因此可以直接提供查询结果,不需要回表。也就是说,在这个查询里面, 索引k已经“覆盖了”我们的查询需求,我们称为覆盖索引

    希望本文章对您有帮助,您的转发、点赞是我的创作动力,十分感谢。更多好文推荐,请关注我的微信公众号--JustJavaIt
  • 相关阅读:
    inotify+rsync做实时同步
    JAVA序列化和反序列化
    初识iBatis
    《Spring in action》之高级装配
    《Spring in action》之装配Bean
    原根
    数论知识
    线性(欧拉)筛
    Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) E DNA Evolution
    Fibonacci
  • 原文地址:https://www.cnblogs.com/liaowenhui/p/15177782.html
Copyright © 2011-2022 走看看