1.索引的本质

news2024/11/13 8:57:39

索引是帮组MYSQL高效获取数据的排好序的数据结构

二叉树

二叉树是树节点的度不大于2的有序树。它是一种最简单最重要的树。

image.png
二叉树的左节点始终小于父节点。二叉树的有节点始终大于等于父节点

image.png
对于单边递增的数据,二叉树会变成链表的形式。这个时候查询不会减少次数。所以也不会减少IO次数。这就是MYSQL没有使用二叉树的原因。

@Data
public class NodeTest {

    int fData;   //数据
    NodeTest leftChild;   //左节点
    NodeTest rightChild;  //右节点

    public NodeTest() {

    }

    public static void main(String[] args) {
        NodeTest nodeTest = new NodeTest();

    }



    static class Tree{
        private NodeTest root;

        public boolean insertNode(NodeTest root1,NodeTest nodeTest){
            if (root == null){
                root = nodeTest;
                return true;
            }else {
                // 代表不为null
                if (root1 == null){
                    root1 = root;
                }
                int fData1 = root1.getFData();
                if (fData1 > nodeTest.getFData()){
                    // 左节点
                    if (root1.getLeftChild() == null){
                        root1.setLeftChild(nodeTest);
                        return true;
                    }else {
                         // 左节点不为null
                        insertNode(root1.getLeftChild(),nodeTest);
                    }
                }else {
                    // 左节点
                    if (root1.getRightChild() == null){
                        root1.setRightChild(nodeTest);
                        return true;
                    }else {
                        // 左节点不为null
                        insertNode(root1.getRightChild(),nodeTest);
                    }
                }
            }
            return false;
        }

        public static void main(String[] args) {
            Tree tree = new Tree();
            NodeTest nodeTest = new NodeTest();
            nodeTest.setFData(3);
            boolean b = tree.insertNode(null, nodeTest);

            NodeTest nodeTest1 = new NodeTest();
            nodeTest1.setFData(5);
            tree.insertNode(null,nodeTest1);

            NodeTest nodeTest2 = new NodeTest();
            nodeTest2.setFData(2);
            tree.insertNode(null,nodeTest2);
            NodeTest nodeTest3 = new NodeTest();
            nodeTest3.setFData(3);
            tree.insertNode(null,nodeTest3);
            System.out.println(b);
        }
    }

}

红黑树

image.png

  1. 每个结点不是红色就是黑色
  2. 根节点是黑色的
  3. 如果一个节点是红色的,则它的两个孩子结点是黑色的(不会出现连在一起的红色节点)
  4. 对于每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点(在计算一条路径中黑色节点个数的时候要带上叶子节点,因为叶子节点也是黑色的,也就是空节点)。
  5. 每个叶子结点都是黑色的(此处的叶子结点指的是空结点)(为了保证空树也是红黑树)
  6. 红黑树确保没有一条路径会比其他路径长出俩倍(红黑树前面的性质保证了当前的性质)

虽然红黑树会根据性质做出对应的旋转,能够减少树的层级。但是对MYSQL而言存储的数据都是十万百万级别的。对应的树的层级还是很高。进行的IO次数也是不可避免的。所以MYSQL也没有使用红黑树(java中的Map和Set存储数据时如果一个桶上的数据大于8的时候会把链表转换为红黑树)。

B树

image.png
B 树也称 B- 树,它是一颗多路平衡查找树。我们描述一颗B树时需要指定它的阶数,阶数表示了一个结点最多有多少个孩子结点,一般用字母m表示阶数。当m取2时,就是我们常见的二叉搜索树。
一颗m阶的B树定义如下:
1)每个结点最多有m-1个关键字。
2)根结点最少可以只有1个关键字。
3)非根结点至少有 Math.ceil(m/2)-1个关键字。
4)每个结点中的关键字都按照从小到大的顺序排列,每个关键字的左子树中的所有关键字都小于它,而右子树中的所有关键字都大于它。
5)所有叶子结点都位于同一层,或者说根结点到每个叶子结点的长度都相同。

B-树每个节点都可以存储多个数据。而且也有红黑树的旋转属性。所以存储数据相同的情况下B数的层级更小。所以IO次数就会少。但是由于每个节点的数据都会存储真实的数据,真实数据往往比较大。所以导致一层节点存储的数据是有限的。所以MYSQL也没有用B树做为索引的存储结构。会用到下面的B+ 树。

B+ 树

image.png

B+ 树是B树的一个变种。B+ 树的非叶子节点不在存储数据。只进行数据索引。叶子节点结构也是有序的。并且每个元素会存储下一个元素的索引和上一个元素的索引。这样就大大增加了每一层非叶子节点存储的数据索引质量了。

假如一个节点能存储16KB、索引占用10b、数据占用1Kb则三层树可以存储多少?

结果\层BB+
1161600
216 * 16 = 2561600 * 1600 = 2560000
3256 * 16 = 40962560000 * 16 = 40960000

大概算了下发现B+ 比 B多存储了四个量级的数据。所以B+ 树IO次数在大数据两下比B树要小的多。

主键索引和联合索引的区别

  1. 主键索引是聚簇索引、联合索引是非聚簇索引。
  2. 主键索引推荐用int类型并且是自增的(减少B+树的旋转和调整)。并且聚簇索引叶子结点存储的是一条数据的所有值。非聚簇索引存叶子结点存储的是主键id。所以如果使用非聚簇索引查询数据,然后使用select * 还需要获取id数据后进行主键索引树中进行回表查询。所以会浪费一部分时间。
  3. 为啥非聚簇索引不存储一整行数据
    1. 为了保证数据一致性和节省空间。
      1. 因为如果索引都存储所有的数据。那每个索引在数据修改的时候都要更改为最新的数据。这个就无法保证了数据的一致性。
      2. 非聚簇索引不保存全部数据就可以减少很都空间。

索引覆盖

通俗来讲就是在执行某个查询语句时进行,在一个索引树(非聚簇索引)上就能查询到需要的字段、而无需回了,这就是索引覆盖。正确是使用好索引覆盖可以减少sql的执行时间。

比如:
创建一个user表:

creat table user(
	id int primary key,
	name varchar(20),
	sex varchar(5)
) engine=innodb;
ALTER TABLE user ADD INDEX index_name (name);: 添加name字段普通索引

如果查询
select id,name,sex from user where name = ‘小白’;
这个sql会先查询name索引树获取符合条件的id列表。然后再回表查询主键索引树获取sex字段数据。这就要拆线呢两次数据。
如果创建一个联合索引就可以不用多查询一次了。
ALTER TABLE user ADD INDEX index_name_sex (name,sex);: 添加name字段普通索引;
这样就拆线呢一次就能获取到所有需要的字段了。

结果:

所以在给表创建索引的时候最好创建联合索引。不要创建单个索引,一张表可以用两三个联合索引能概括全你所有的查询。不要使用select * 查询数据。每次查询最好返回自己有用的数据。不要返回无用的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1229879.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vatee万腾外汇市场新力量:vatee科技决策力

在当今数字化时代,Vatee万腾崭露头角,以其强大的科技决策力进军外汇市场,成为该领域的新力量。这一新动向将不仅塑造外汇市场的未来,也展现Vatee科技决策力在金融领域的引领作用。 Vatee万腾带着先进的科技决策力进入外汇市场&…

ChatGPT 从零完全上手实操指南!

那么,在正式开始前,我这里有必要说明一下: 关于 GPT 的基本面介绍,以及怎么注册,这些搜索引擎一搜一大把的东西,我们这里不浪费口舌。 PS:为了照顾一些无特殊环境的同学,文中也会提供…

大批量合并识别成一个表或文档的方法

金鸣表格文字识别系统功能强大,其中可以将上百张图片或上百页PDF中的表格文字合并识别成一个表格或文档的功能尤其受到广大用户的欢迎,那应该怎么操作呢? 一、打开金鸣表格文字识别软件,点击左上角的“表格识别”,选择…

(亲测有效)VMware Windows虚拟机扩容

场景: VMware安装了一个windows系统,现在windows系统剩余空间不足,需要扩容。 解决步骤: 关闭虚拟机,状态如下: 2、点击编辑虚拟机设置-》扩展 3、输入最大磁盘大小-》点击扩展 4、等待成功后&#xff0c…

Django 路由配置(二)

一、路由 就是根据用户请求的URL链接来判断对应的出来程序,并返回处理结果,也是就是URL和django的视图建立映射关系. 二、Django请求页面的步骤 1、首先Django确定要使用的根URLconf模块,通过ROOT_URLCONF来设置,在settings.py配置…

spring-boot-maven-plugin插件 —— 打包时减小jar包的大小方法

Maven 在打包时会将所依赖的 jar 包全部打包进去,包含了所有的依赖和资源文件,就会导致打出来的包比较大。如果再上传服务器,那么耗时特别长。 由于依赖包变化小,占用空间大,而且大部分情况是添加一次后,就…

MPN在QM中的使用

此文章为机器翻译SAP BLOG 文章,原文地址:Manufacturer Part Profile in QM | SAP Blogs 目的:–材料管理 (MM) 组件支持从不同供应商采购制造商特定的零件或材料。如果您实施制造商零件编号 (MPN) 处理功能,您还可以在质量管理 …

DV,OV通配符的区别

通配符证书是经常提及的一种SSL证书类型,也被称为泛域名证书。所有的通配符证书都具有保护主域名及其下一级所有子域名的功能。按照验证方式的不同,可以把通配符证书划分为DV通配符(基础型)和OV通配符(组织型&#xff…

Docker之微服务实战(一个小的java的jar包发布运行测试test)

Docker微服务实战 1、通过IDEA新建一个普通微服务模块 (在工具idea里面新建项目…,) 通过dockerfile发布微服务部署到docker容器 2、IDEA工具里面搞定微服务jar包 docker_boot-0.0.1-SNAPSHOT.jar 3、编写Dockerfile # 基础镜像使用java FR…

【每日一题】最大子数组和

文章目录 Tag题目来源题目解读解题思路方法一:动态规划方法二:分治方法三:前缀和 写在最后 Tag 【动态规划】【前缀和】【数组】【2023-11-20】 题目来源 53. 最大子数组和 题目解读 找出数组 nums 中连续子数组元素和的最大值。数组中的元…

echarts 实现3D立体柱状图示例

该示例有如下几个特点: ①实现tooltip自定义样式(echarts 实现tooltip提示框样式自定义-CSDN博客) ②数据为0时,顶部四边形不展示 ③legend图标设置为自定义图片 【第②也是一个难点,我没有找到其他解决办法&#xff…

JZM-D30室温探针台技术参数

概况: JZM-D30室温探针台的诸多设计都是专用的,探针台的配置主要是根据用户的需求进行选配及设计。例如,要求的磁场型号,电源型号,磁场值,样品台的尺寸等,除此之外,该探针台和我司自…

装备中国功勋企业——兰石重装,建设LTC全流程管理|基于得帆云低代码的CRM案例系列

兰石重型装备股份有限公司 兰石重型装备股份有限公司(以下简称“兰石重装”)成立于2001年,经营范围为炼油、化工、核电等能源领域所需的装备的设计、制造、安装、成套与服务;工程项目建设与服务;机械加工;检…

高版本Vivado和Linux 4.x内核移植Digilent Driver

移植环境 Vivado 2022.2Ubuntu 22.04petalinux 2022.2Linux内核4.14(xilinx-linux-2018.3)linux-digilent 主要问题 https://github.com/Digilent/linux-digilent 这些驱动支持Linux kernel release 4.x,然而和Vitis 2022.2 套件对应的内核…

Microsoft Visual Studio 2019下载及安装流程记录

第一周任务: 1.笔记本上安装vc2019的环境 2.再把OpenCV安装上 3.根据网上的教程,试着写几个opencv的程序 一、安装Visual Studio 2019社区版 首先先完成安装vc2019的环境, 因为: Microsoft Visual C是用于C编程的工具集合&am…

华为昇腾阿木实验室FMT,开展无人飞艇开发者线下体验活动!

活动背景 气球机器人是一种利用气球作为飞行平台的可编程飞行器,它利用浮力作为主要升力,在灵活性、稳定性和安全性方面展示了巨大的潜力。近年来,这些机器人已在航拍、气象观测、水文学、侦察和特勤等领域发挥了重要作用。 气球机器人是未来…

Chrome中设置安全来源域名

目的: 使得本地映射的域名能被浏览器安全访问,允许调用设备资源 步骤: 在Chrome中导航栏打开 chrome://flags/#unsafely-treat-insecure-origin-as-secure 填入hosts域名:如 http://h5-twzc003.local.com 参考: h…

带哨兵位的单链表

认识 链表分为两种:带头结点的和不带头结点的 之前我们学习了不带哨兵位的单链表,并实现了相关代码 现在我们认识一下带哨兵位头结点的单链表: plist指向带哨兵位的头结点 这个结点不存储有效数据 如果为空链表: 不带头&#…

在Python中调用imageJ开发

文章目录 一、在ImageJ中进行Python开发二、在Python中调用imageJ开发2.1、简介2.2、环境配置2.3、测试一2.4、测试二 Python imageJ 解决方案,采坑记录 一、在ImageJ中进行Python开发 原生ImageJ仅支持JS脚本(JAVAScript),而Im…

milvus采坑一:启动服务就会挂掉

原因一 硬盘满了,Eric数据文件存储在硬盘上,当硬盘不足,它就会启动后就挂掉。 此时pymilvus连接一直是timeout。 解决方法:更换存储路径。