zoukankan      html  css  js  c++  java
  • 聚集索引,非聚集索引,覆盖索引

    https://blog.csdn.net/itguangit/article/details/82145322

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

                   一个没有主键的表,在数据无序的存储在磁盘上;

                一个表加了主键,这个表在磁盘上的存储结构就转变为树状结构,即平衡树结构,同时也是索引;

               此时整个表变为一个索引,即 聚集索引

     

    聚集索引:

                   也称为 主键索引

                   表中的数据按照索引的顺序存储,即索引存储着数据, 检索效率比非聚集索引高,但是对数据更新影响大,因为修改数据会改变平衡树各个节点的内容;破坏树得到结构;

                   聚集索引就是按照每张表的主键构造一颗B+树,同时叶子节点中存放的即为整张表的记录数据。

                   聚集索引的叶子节点称为数据页,聚集索引的这个特性决定了索引组织表中的数据也是索引的一部分。

     

         

    非聚集索引

                   也称为 辅助索引(二级索引)

                   和聚集索引一样,采用平衡树作为索引的数据结构。索引树结构中各节点的值来自于表中的索引字段, 假如给user表的name字段加上索引 , 那么索引就是由name字段中的值构成,在数据改变时, DBMS需要一直维护索引结构的正确性。如果给表中多个字段加上索引 , 那么就会出现多个独立的索引结构,每个索引(非聚集索引)互相之间不存在关联。

                   非主键索引,叶子节点=键值+书签。Innodb存储引擎的书签就是相应行数据的主键索引值

                   每次给字段建一个新索引, 字段中的数据就会被复制一份出来, 用于生成索引。 因此, 给表添加索引,会增加表的体积, 占用磁盘存储空间。

     

    //建立索引
    
    create index index_birthday on user_info(birthday);
    
    //查询生日在1991年11月1日出生用户的用户名
    
    select user_name from user_info where birthday = '1991-11-1'

             SQL语句的执行过程如下:

                   先通过非聚集索引 index_birthday 查找 birthday 为 1991-11-1 的所有记录的主键ID值。

                   然后,通过得到的主键ID值执行聚集索引查找,找到主键ID值对的真实数据(数据行)存储的位置。

                   最后,从得到的真实数据中取得 user_name 字段的值返回。

          

    非聚集索引和聚集索引:

                   区别在于, 通过聚集索引可以查到需要查找的数据, 而通过非聚集索引可以查到记录对应的主键值 , 再使用主键的值通过聚集索引查找到需要的数据,如下图

        

    覆盖索引:

                   就是平时所说的复合索引或者多字段索引查询。 文章上面的内容已经指出, 当为字段建立索引以后, 字段中的内容会被同步到索引之中, 如果为一个索引指定两个字段, 那么这个两个字段的内容都会被同步至索引之中。

                   就是select的数据列只用从索引中就能够取得,不必从数据表中读取,换句话说查询列要被所使用的索引覆盖。

                   索引是高效找到行的一个方法,当能通过检索索引就可以读取想要的数据,那就不需要再到数据表中读取行了。如果一个索引包含了(或覆盖了)满足查询语句中字段与条件的数据就叫 做覆盖索引。

                   是非聚集组合索引的一种形式,它包括在查询里的Select、Join和Where子句用到的所有列(即建立索引的字段正好是覆盖查询语句[select子句]与查询条件[Where子句]中所涉及的字段,也即,索引包含了查询正在查找的所有数据)

                   把 birthday 字段上的索引改成双字段的覆盖索引     

    create index index_birthday_and_user_name on user_info(birthday, user_name);

                  SQL语句的执行过程就会变为:

                 通过非聚集索引index_birthday_and_user_name查找birthday等于1991-11-1的叶节点的内容,然而, 叶节点中除了有user_name表主键ID的值以外, user_name字段的值也在里面, 因此不需要通过主键ID值的查找数据行的真实所在, 直接取得叶节点中user_name的值返回即可。

  • 相关阅读:
    SwiftyUserDefaults-封装系统本地化的框架推荐
    转:AFNetworking 与 UIKit+AFNetworking 详解
    转:KVC/KVO原理详解及编程指南
    转:NSString什么时候用copy,什么时候用strong
    代码重构原则
    转:【iOS开发每日小笔记(十一)】iOS8更新留下的“坑” NSAttributedString设置下划线 NSUnderlineStyleAttributeName 属性必须为NSNumber
    转:iOS程序main函数之前发生了什么
    转:iOS 屏幕适配,autoResizing autoLayout和sizeClass图文详解
    Apple macOS Mojave Intel Graphics Driver组件任意代码执行漏洞
    巧用"记事本"让病毒无效运行
  • 原文地址:https://www.cnblogs.com/Jomini/p/13213846.html
Copyright © 2011-2022 走看看