Mysql B+树索引

一、联合索引

内节点中存储的是 目录项 记录 ,叶子节点中存储的是 用户记录 (由于不是聚簇索引,所以用户记录是不完整的,缺少 country 列的 值)。这个 idx_name_birthday_phone_number 索引对应的 B+ 树中页面和记录的排序方式就是 这样的: 
先按照 name 列的值进行排序。 
如果 name 列的值相同,则按照 birthday 列的值进行排序。 
如果 birthday 列的值也相同,则按照 phone_number 的值进行排序。 

二、索引匹配原则

2.1 最左匹配原则

我们想使用联合索引中尽可能多的列,搜索条件中的各个列必须是联合索引中从最左边连续的列。

2.2 匹配范围查询

2.2.1 示例

如果对多个列同时进行范围查找的话,只有对索引最左边的那个 列进行范围查找的时候才能用到 B+ 树索引,比如:
SELECT * FROM person_info WHERE name > 'Asa' AND name < 'Barlow' AND birthday > '1980-01-0 1';查询分成两部分:
1. 通过条件 name > 'Asa' AND name < 'Barlow' 来对 name 进行范围,查找的结果可能有多条 name 值不同的 记录。
2. 对这些 name 值不同的记录继续通过 birthday > '1980-01-01' 条件继续过滤。

只能用到 name 列的部分,而用不到 birthday 列 的部分,因为只有 name 值相同的情况下才能用 birthday 列的值进行排序,而这个查询中通过 name 进行范围查 找的记录中可能并不是按照birthday 列进行排序的,在搜索条件中继续以 birthday 列进行查找时是用不到 这个 B+ 树索引的。

2.2.2 示例:精确匹配某一列并范围匹配另外一列

SELECT * FROM person_info WHERE name = 'Ashburn' AND birthday > '1980-01-01' AND birthday < '2000-12-31' AND phone_number > '15100000000';
这个查询的条件可以分为3个部分:
1. name = 'Ashburn' 对 name 列进行精确查找,当然可以使用 B+ 树索引了。 
2. birthday > '1980-01-01' AND birthday < '2000-12-31' ,由于name 列是精确查找,所以通过 name = 'Ashburn' 条件查找后得到的结果的 name 值都是相同的,它们会再按照 birthday 的值进行排序。所以此时 对 birthday 列进行范围查找是可以用到 B+ 树索引。 
3. phone_number > '15100000000' ,通过 birthday 的范围查找的记录的 birthday 的值可能不同,所以这个条件无法再利用 B+ 树索引了只能遍历上一步查询得到的记录。
4. 同理,下边的查询也是可能用到这个 idx_name_birthday_phone_number 联合索引的: SELECT * FROM person_info WHERE name = 'Ashburn' AND birthday = '1980-01-01' AND AND phone _number > '15100000000';

三 order 排序与分组

3.1 能使用到索引

按照最左匹配原则,也能使用到索引

3.2 不能使用到索引

1、ASC、DESC混用
2、WHERE子句中出现非排序使用到的索引列
3、排序列包含非同一个索引的列
4、排序列使用了复杂的表达式

3.3 group by 分组 :需要满足最左匹配原则

SELECT name, birthday, phone_number, COUNT(*) FROM person_info GROUP BY name, birthday, ph one_number;
1. 先把记录按照 name 值进行分组,所有 name 值相同的记录划分为一组。
2. 将每个 name 值相同的分组里的记录再按照 birthday 的值进行分组,将 birthday 值相同的记录放到一个小 分组里,所以看起来就像在一个大分组里又化分了好多小分组。 
3. 再将上一步中产生的小分组按照 phone_number 的值分成更小的分组,所以整体上看起来就像是先把记录分 成一个大分组,然后把 大分组 分成若干个 小分组 ,然后把若干个 小分组 再细分成更多的 小小分组 。

四 如何建立索引

1、只为用于搜索、排序或分组的列创建索引
2、考虑列的基数

        列的值种类越多越适合建立索引
3、索引列的类型尽量小

    数据类型越小,在查询时进行的比较操作越快(这是CPU层次的东东)
    数据类型越小,索引占用的存储空间就越少,在一个数据页内就可以放下更多的记录,从而减少磁盘 I/O 带来的性能损耗,也就意味着可以把更多的数据页缓存在内存中,从而加快读写效率。
4、索引字符串值的前缀
5、让索引列在比较表达式中单独出现
6、主键插入顺序
7、冗余和重复索引

五 总结

1. B+ 树索引在空间和时间上都有代价,所以没事儿别瞎建索引。
2. B+ 树索引适用于下边这些情况:
    全值匹配
    匹配左边的列
    匹配范围值
    精确匹配某一列并范围匹配另外一列
    用于排序
    用于分组
3. 在使用索引时需要注意下边这些事项:
    只为用于搜索、排序或分组的列创建索引
    为列的基数大的列创建索引
    索引列的类型尽量小
    可以只对字符串值的前缀建立索引
    只有索引列在比较表达式中单独出现才可以适用索引
    为了尽可能少的让 聚簇索引 发生页面分裂和记录移位的情况,让主键AUTO_INCREMENT。
    定位并删除表中的重复和冗余索引
    尽量使用 覆盖索引 进行查询,避免 回表 带来的性能损耗。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

服务器数据恢复-服务器RAID6硬盘故障离线的数据恢复案例

服务器数据恢复环境&#xff1a; 服务器中有一组由6块磁盘组建的RAID6磁盘阵列。服务器作为WEB服务器使用&#xff0c;上面运行了MYSQL数据库以及存放了网站代码和其他数据文件。 服务器故障&#xff1a; 在服务器运行过程中该raid6阵列中有两块磁盘先后离线&#xff0c;但是管…

Spring与MyBatis集成 AOP整合PageHelper插件

目录 1.什么是集成&#xff1f; 2.Spring与MyBatis集成 3.Spring与MyBatis集成的基本配置 4.AOP整合PageHelper插件 1.什么是集成&#xff1f; 集成是指将不同的组件、框架或系统整合到一起&#xff0c;使它们可以协同工作、相互调用、共享资源等。通过集成&#xff0c;可以…

乡村振兴战略下传统村落文化旅游设计书辉瑞

乡村振兴战略下传统村落文化旅游设计书辉瑞

07:STM32----ADC模数转化器

目录 1:简历 2:逐次逼近型ADC 3:ADC基本结构 4:输入通道 5:规则组的4种转换模式 1:单次转化,非扫描模式 2:连续转化,非扫描模式 3:单次转化,扫描模式 4:单次转化,扫描模式 6:触发控制 7:数据对齐 8:转化时间 9:校准 10:ADC的硬件电路 A: AD单通道 1:连接图 2:函…

ARDUINO STM32 SSD1306

STM32F103XX系列SPI接口位置 在ARUDINO 下&#xff0c;&#xff08;不需要设置引脚功能&#xff0c;不需要开启时钟设置&#xff0c;ARDUINO已经帮我们处理了&#xff09; stm32f103c6t6 flash不足&#xff0c;不足以运行U8G2,产生错误 改用U8X8&#xff0c;后将字体改为u8x8_…

什么是网络取证(Network Forensics)

企业采用新技术来检查其网络安全是否存在零日漏洞&#xff0c;与立即指示问题的物理层不同&#xff0c;黑客攻击尝试可能会被忽视并变得严重&#xff0c;直到对网络流量有一个整体的可见性。通过实时监控来跟踪其源和目标的流量&#xff0c;以查明问题或潜在问题的根源。 什么…

JavaScript—数据类型、对象与构造方法

js是什么&#xff1f; JavaScript&#xff08;简称“JS”&#xff09; 是一种具有函数优先的轻量级&#xff0c;解释型或即时编译型的编程语言。JavaScript 基于原型编程、多范式的动态脚本语言&#xff0c;并且支持面向对象、命令式、声明式、函数式编程范式。 js有哪些特点呢…

1.1 数据库系统简介

思维导图&#xff1a; 1.1.数据库系统简介 前言&#xff1a; 数据库系统是一个软件系统&#xff0c;用于管理和操作数据库。它提供了一个组织良好、高效并能够方便存取的数据存储机制&#xff0c;并且能够支持各种数据操作、事务管理、并发控制和恢复功能。以下是数据库系统的…

为什么 Higress 是 Knative 入口网关的最佳实践?

作者&#xff1a;赵伟基&#xff08;兆维&#xff09; 在传统的应用开发中&#xff0c;通常需要管理底层的基础设施、服务器与网络配置等方面的工作。然而在云原生 Serverless 化的浪潮下&#xff0c;这些基础设施的细节被抽象和自动化&#xff0c;开发者无需关注服务器等配置…

嵌入式实时操作系统的设计与开发

时钟管理 在RTOS中&#xff0c;时钟具有非常重要的作用&#xff0c;通过时钟可实现延时任务、周期性触发任务执行、任务有限等待的计时。 大多数嵌入式系统有两种时钟源&#xff0c;分别为实时时钟RTC&#xff08;Real-Time Clock&#xff09;和定时器/计数器。 实时时钟一般…

React Antd form.getFieldsValue() 和 form.getFieldsValue(true) 有区别吗?

背景 突然发现 antd 的 getFieldsValue()是可以传一个 true 参数的&#xff0c;如题,React Antd form.getFieldsValue() 和 form.getFieldsValue(true) 有区别吗&#xff1f; 验证 确实不一样 结论 getFieldsValue 提供了多种重载方法&#xff1a; getFieldsValue(name…

开学季,“护眼教室”上线,守护孩子光明未来

在关于教室的记忆里&#xff0c;你是否有着这样的滤镜&#xff1f; “电影”滤镜&#xff1a;模糊又遥远&#xff0c;夜间自习像褪色的胶片。 “眩光”滤镜&#xff1a;灯光亮到出现“光环”&#xff0c;看不了多久眼睛就酸胀。 “频闪”滤镜&#xff1a;头顶的灯仿佛飞速眨眼…