zoukankan      html  css  js  c++  java
  • 联合索引在B+树上的结构

    一级索引

    二级联合索引

    假设这是一个多列索引(col1, col2,col3),对于叶子节点,是这样的: 

    PS:该图改自《MySQL索引背后的数据结构及算法原理》一文的配图。

    也就是说,联合索引(col1, col2,col3)也是一棵B+Tree,其非叶子节点存储的是第一个关键字的索引,而叶节点存储的则是三个关键字col1、col2、col3三个关键字的数据,且按照col1、col2、col3的顺序进行排序。

    配图可能不太让人满意,因为col1都是不同的,也就是说在col1就已经能确定结果了。自己又画了一个图(有点丑),col1表示的是年龄,col2表示的是姓氏,col3表示的是名字。如下图: 

    PS:对应地址指的是数据记录的地址。

    如图,联合索引(年龄, 姓氏,名字),叶节点上data域存储的是三个关键字的数据。且是按照年龄、姓氏、名字的顺序排列的。

    因此,如果执行的是: 
    select * from STUDENT where 姓氏='李' and 名字='安'; 
    或者 
    select * from STUDENT where 名字='安'; 
    那么当执行查询的时候,是无法使用这个联合索引的。因为联合索引中是先根据年龄进行排序的。如果年龄没有先确定,直接对姓氏和名字进行查询的话,就相当于乱序查询一样,因此索引无法生效。因此查询是全表查询。

    如果执行的是: 
    select * from STUDENT where 年龄=1 and 姓氏='李'; 
    那么当执行查询的时候,索引是能生效的,从图中很直观的看出,age=1的是第一个叶子节点的前6条记录,在age=1的前提下,姓氏=’李’的是前3条。因此最终查询出来的是这三条,从而能获取到对应记录的地址。 
    如果执行的是: 
    select * from STUDENT where 年龄=1 and 姓氏='黄' and 名字='安'; 
    那么索引也是生效的。

     

    而如果执行的是: 
    select * from STUDENT where 年龄=1 and 名字='安'; 
    那么,索引年龄部分能生效,名字部分不能生效。也就是说索引部分生效。

    因此我对联合索引结构的理解就是B+Tree是按照第一个关键字进行索引,然后在叶子节点上按照第一个关键字、第二个关键字、第三个关键字…进行排序。

    最左原则

    而之所以会有最左原则,是因为联合索引的B+Tree是按照第一个关键字进行索引排列的。

    MySQL InnoDB聚簇及辅助索引

  • 相关阅读:
    套接字中的setsockopt接口功能
    memmove()函数介绍
    static 关键字和类的加载顺序
    Navicat 链接mysql 显示 Clinet dose not support authentication protocol request by server ;consider upgrading MySQL client
    maven项目引入依赖之后,jar包没有自动导入报错
    @RequestParam 和@RequestBody 的区别?
    java中 & ^ ~ 的运算
    form表单post请求乱码问题
    struts2+hibernate3.2分页
    AJAX建立和服务器连接,接收服务器技术处理服务器返回的数据
  • 原文地址:https://www.cnblogs.com/wuchanming/p/9185661.html
Copyright © 2011-2022 走看看