第 7 章 B+树索引的使用

news2024/12/23 18:14:12

7.1 索引的代价

  1. 空间上的代价

    每建立一个索引都要为它建立一棵B+树,B+树的每一个节点都是一个数据页,一个页默认占用16KB的空间。

  2. 时间上的代价

    每次对表中的数据进行增、删、改操作时,都需要去修改各个B+树索引。

一个表上的索引越多,占用的空间也就越多,增删改时的性能也就越关。

7.2 B+树索引适用的条件

CREATE TABLE person_info(
	id INT NOT NULL auto_increment,
	name VARCHAR(100) NOT NULL,
	birthday DATE NOT NULL,
	phone_number CHAR(11) NOT NULL,
	country varchar(100) NOT NULL,
	PRIMARY KEY (id),
	KEY idx_name_birthday_phone_number (name, birthday, phone_number)
);

二级索引示意图

7.2.1 全值匹配
SELECT * FROM person_info WHERE name = 'Ashburn' AND birthday = '1990-09-27' AND phone_number = '15123983239';

联合索引中的三个列都可能被用到。

调整name,birthday,phone_number三列的顺序不会影响使用索引,查询优化器会搞定。

7.2.2 匹配左边的列

可以使用索引的写法:

SELECT * FROM person_info WHERE name = 'Ashburn';
SELECT * FROM person_info WHERE name = 'Ashburn' AND birthday = '1990-09-27';

不可以使用索引的写法:

SELECT * FROM person_info WHERE birthday = '1990-09-27';

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

7.2.3 匹配列前缀

因为字符串排序时,是按一个字符一个字符比较的,所以一个排好序的字符串列,他们的前缀也是排好序的。所以以下SQL可以使用索引

SELECT * FROM person_info WHERE name LIKE 'As%';

但是这样

SELECT * FROM person_info WHERE name LIKE '%As%';

就不能使用索引。因为字符串中间有"As"的字符串并没有排好序。

7.2.4 匹配范围值
SELECT * FROM person_info WHERE name > 'Asa' AND name < 'Barlow';
  1. 定位到name="Asa"的记录
  2. 定位到name="Barlow"的记录
  3. 由于所有记录都是链表连起来的,取出他们中间的记录的主键值
  4. 聚簇索引回表查询
SELECT * FROM person_info WHERE name > 'Asa' AND name < 'Barlow' AND birthday > '1980-01-01';

只可以使用name列的索引。因为只有name值相同时才能用birthday的值进行排序,而这个查询中通过name进行范围查找中的记录可能并不是按照birthday列进行排序的,所以无法使用birthday列的索引。

7.2.5 精确匹配某一列并范围匹配另外一列
SELECT * FROM person_info WHERE name = 'Ashburn' AND birthday > '1980-01-01' AND birthday< '2000-12-31' AND phone_number > '15100000000';

可以使用name列和birthday列的索引。

SELECT * FROM person_info WHERE name = 'Ashburn' AND birthday = '1980-01-01' AND AND phone_number > '15100000000';

可以使用整个联合索引。

7.2.6 用于排序

filesort:文件排序,在MySQL中,当查询的结果集太大不能在内存中进行排序时,暂时借助磁盘的空间来存放中间结果,排序操作完成后再把排好序的结果集返回到客户端。

SELECT * FROM person_info ORDER BY name, birthday, phone_number LIMIT 10;

可以直接使用idx_name_birthday_phone_number 索引。

7.2.6.1 使用联合索引进行排序注意事项

ORDER BY 的子句顺序要与索引顺序保持一致(这里可没有查询优化器进行优化哦)。

同样遵循最左匹配。

SELECT * FROM person_info WHERE name = 'A' ORDER BY birthday, phone_number LIMIT 10;

也可以使用索引进行排序。

7.2.6.2 不可以使用索引进行排序的几种情况
  1. ASC、DESC 混用。B+树中都是升序排序的,降序查询时,无法使用索引。
  2. WHERE 子句中出现非排序使用到的索引列。
  3. 排序列包含非同一个索引的列。
  4. 排序列使用了复杂的表达式。
7.2.7 用于分组
SELECT name, birthday, phone_number, COUNT(*) FROM person_info GROUP BY name, birthday, phone_number

分组条件与索引相同,可以直接使用B+树索引进行分组。

7.3 回表的代价

SELECT * FROM person_info WHERE name > 'Asa' AND name < 'Barlow';

查询分两步:

  1. 从索引idx_name_birthday_phone_number 对应的B+树中取出name在Asa~Barlow之间的用户记录。
  2. 根据上一步查询出来的主键到聚簇索引中找到完整的用户记录,即回表查询。

该查询有两个特点:

  1. 会使用两个B+树索引,一个二级索引,一个聚簇索引
  2. 访问二级索引使用顺序I/O,速度较快;访问聚簇索引使用随机I/O,速度较慢。

**需要回表的记录越多,使用二级索引的效率也就越低。**特殊情况下,查询器宁愿使用全表扫描也不使用二级索引。

PS:因为Asa~Barlow之间的用户记录在磁盘中的存储是相连的,集中在一个或几个数据页中,称为顺序I/O。而通过这些用户记录的ID去定位数据,因为ID可能并不相连,所以他们指向的数据可能分布在更多的数据页,因此要访问的数据页也就更多,称为随机I/O。

7.3.1 覆盖索引

索引列包含所有查询列时可以避免回表,这样的索引称为覆盖索引。

7.4 如何挑选索引

7.4.1 只为用于搜索、排序或分组的列创建索引

只为出现在WHERE子句中的列、连接子句中的连接列,或者出现在ORDER BYGROUP BY子句中的列创建索引。

7.4.2 考虑列的基数

即选择性。

7.4.3 索引列的类型尽量小
  1. 数据类型越小,在查询时进行的比较操作越快(CPU级别)
  2. 数据类型越小,索引占用的存储空间就越少,在一个数据页内记录就越多,I/O次数就越少。
7.4.4 索引字符串值的前缀

只对字符串的前几个字符建立索引

CREATE TABLE person_info(
    name VARCHAR(100) NOT NULL,
    birthday DATE NOT NULL,
    phone_number CHAR(11) NOT NULL,
    country varchar(100) NOT NULL,
    KEY idx_name_birthday_phone_number (name(10), birthday, phone_number)
);

name(10)就表示在建立的B+树索引中只保留记录的前10个字符的编码,这种只索引字符串值的前缀的策略是我们非常鼓励的,尤其是在字符串类型能存储的字符比较多的时候。

7.4.5 让索引列在比较表达式中单独出现

如果索引列在比较表达式中不是以单独形式出现,而是以某个表达式,或者函数调用形式出现的话,是用不到索引的。

7.4.6 主键插入顺序

无顺的主键插入可能会导致页面分裂和记录移位,影响性能。所以尽量保持主键依次递增,让主键具有AUTO_INCREMENT,让存储引擎自己为表生成主键,而不是我们手动插入。

7.4.7 冗余和重复索引
CREATE TABLE person_info(
    id INT UNSIGNED NOT NULL AUTO_INCREMENT,
    name VARCHAR(100) NOT NULL,
    birthday DATE NOT NULL,
    phone_number CHAR(11) NOT NULL,
    country varchar(100) NOT NULL,
    PRIMARY KEY (id),
    KEY idx_name_birthday_phone_number (name(10), birthday, phone_number),
    KEY idx_name (name(10))
);

idx_name重复了。

7.5 总结

  1. B+树索引在空间和时间上都有代价,使用时要有敬畏之心
  2. B+树索引适用以下情况
    • 全值匹配
    • 匹配左边的列
    • 匹配范围值
    • 精确匹配某一列并范围匹配另外一列
    • 排序
    • 分组
  3. 在使用索引时,需要注意
    • 只为用于索引、排序或分组的列创建索引
    • 为列的基数大的列(选择性强)的列创建索引
    • 索引列的类型尽量小
    • 可以只对字符串值的前缀建立索引
    • 只有索引列在比较表达式中单独出现才有效
    • 为了避免页面分裂和记录移位,使用主键自增
    • 避免重复和冗余索引
    • 尽量使用覆盖索引,避免回表

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

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

相关文章

从零上手CV竞赛Task2 # Datawhale AI夏令营

文章目录 平台参赛平台云平台 Task 1 从零上手CV竞赛下载baseline相关文件一键运行baseline&#xff01;&#xff08;大约需要25分钟&#xff09;赛题解析数据集提交结果违法标准注意事项 下载生成的文件结果如图最后要记得关机 不然一直消耗算力 Task 2 建模方案解读与进阶物体…

光性能 -- OMA(光调制幅度)

基本概念 OMA&#xff08;Optical Modulation Amplitude&#xff09;&#xff1a;光调制幅度&#xff0c;是光信号测试中的一项指标。是指光模块接收到的信号”1”的光功率和信号“0”的光功率的差值。即&#xff1a; Pavg&#xff08;average optical power&#xff09;&#…

WxPython可视化编辑器

作者&#xff1a;陈炳强 WxPython是python的一个用来写桌面程序的模块,目前只写了小部分功能跟组件, 用Python写中文&#xff0c;非常方便&#xff01; 下载地址&#xff1a;https://pan.quark.cn/s/ba19b2472246

LabVIEW如何适应航天系统的要求

随着航天任务的复杂性和精确性要求不断提高&#xff0c;软件系统在其中扮演的角色变得愈发关键。LabVIEW凭借其强大的实时数据处理能力、高可靠性、以及灵活的系统集成和仿真工具&#xff0c;已逐渐成为满足航天系统需求的重要开发平台。通过全面适应航天工程的严格标准&#x…

守护电动“心脏”!仿真APP在汽车电池包随机振动分析中的应用

汽车电动化、智能化、绿色化发展已成为全球各国应对气候变化、实现低碳发展的共同选择。在此背景下&#xff0c;新能源汽车持续高速发展。电池包作为新能源汽车的“心脏”&#xff0c;是其主要动力来源&#xff0c;直接影响车辆的续航里程与行驶安全。电池包结构的安全可靠性对…

Linux——性能调优工具一览

一、CPU 1.调优工具 根据指标找工具 性能指标工具说明 平均负载 uptime、top uptime最简单、top提供了更全的指标 系统整体CPU使用率 vmstat、mpstat、top、sar、/proc/stat top、vmstat、mpstat只可以动态查看&#xff0c;而sar还可以记录历史数据 /proc/stat是其他性…

界面控件Telerik UI for ASP.NET Core 2024 Q2亮点 - AI与UI的融合

Telerik UI for ASP.NET Core是用于跨平台响应式Web和云开发的最完整的UI工具集&#xff0c;拥有超过60个由Kendo UI支持的ASP.NET核心组件。它的响应式和自适应的HTML5网格&#xff0c;提供从过滤、排序数据到分页和分层数据分组等100多项高级功能。 本文将介绍界面组件Teler…

【MySQL 11】索引 (带思维导图)

文章目录 &#x1f308; 一、索引介绍⭐ 1. 索引的概念⭐ 2. 索引的分类⭐ 3. 索引的价值 &#x1f308; 二、认识磁盘⭐ 1. MySQL 与存储⭐ 2. 磁盘的物理结构⭐ 3. 磁盘的随机访问与连续访问 &#x1f308; 三、MySQL 与磁盘交互⭐ 1. MySQL 与磁盘交互的基本单位⭐ 2. MySQL…

一文深度了解堆

什么是堆&#xff1f; 堆&#xff08;Heap&#xff09;是一种基于数组的树形数据结构&#xff0c;其中每个节点都有一个值&#xff0c;且每个节点的值都大于等于&#xff08;或小于等于&#xff09;其子节点的值。堆分为大顶堆&#xff08;Max Heap&#xff09;和小顶堆&#…

回答网友一个C#对话框位置的问题

起因 ‭ 2024-08-28 19:40:20 colorDialog 打开出现的 位置控制不了 鸽子 2024-08-28 20:06:06 你是可以控制的 ‭ 0:00:47 试了下没用&#xff0c;可能是系统 问题吧 代码 位置的设置 SetWindowPos(hWnd, IntPtr.Zero, 0, 0, 0, 0, 1); 核心代码 protected override IntPt…

django学习入门系列之第十点《django的模板语法》

文章目录 获取请求与响应request获取请求方式在url中传递值在结构体中传递值返回一个值读取HTML中的内容 重定向&#xff08;跳转网页&#xff09;往期回顾 获取请求与响应 request request是一个对象&#xff0c;封装了用户通过浏览器发送过来的所有数据获取请求方式 获取请…

Ai产品经理的探索:技能、机遇与未来展望

Ai时代的产品经理 随着人工智能&#xff08;AI&#xff09;的飞速发展&#xff0c;AI已经从一个前沿技术概念逐步演变为驱动各行业创新的核心力量。从智能助手到自动驾驶&#xff0c;从个性化推荐系统到图像识别&#xff0c;AI正在以不可思议的速度改变着我们的生活方式和工作…

python解释器[源代码层面]

1 PyDictObject 在c中STL中的map是基于 RB-tree平衡二元树实现&#xff0c;搜索的时间复杂度为O(log2n) Python中PyDictObject是基于散列表(散列函数)实现&#xff0c;搜索时间最优为O(1) 1.1 散列列表 问题&#xff1a;散列冲突&#xff1a;多个元素计算得到相同的哈希值 …

华为IS-IS实验及配置

AR1配置 #进入ISIS进程 isis 1 #配置设备类型为Level-1is-level level-1 #定义区域和System-ID等信息network-entity 49.0001.0010.0000.0001.00 #ISIS邻居命名is-name AR1 #接口配置IP和启用ISIS interface GigabitEthernet0/0/0ip address 10.1.12.1 255.255.255.0 isis ena…

【C++】C++ STL 探索:String的使用与理解

C语法相关知识点可以通过点击以下链接进行学习一起加油&#xff01;命名空间缺省参数与函数重载C相关特性类和对象-上篇类和对象-中篇类和对象-下篇日期类C/C内存管理模板初阶 这篇文章将带大家深入探讨C STL中的string使用与理解。在接下来的几篇文章中&#xff0c;我们将介绍…

WT2605C蓝牙语音芯片:引领糖尿病管理智能化,优化血糖仪音频与蓝牙传输方案

开发背景 全球糖尿病成人患者数量截至2021年约为5.37亿&#xff0c;并预计到2045年将增长至7.83亿。患病率不仅随年龄增长&#xff0c;还展现出明显的地域差异&#xff0c;例如巴基斯坦的患病率最高。此外&#xff0c;老年人群和某些特定地区的居民面临更高的糖尿病风险。 语音…

Leetcode 22. 括号生成 回溯 C++实现

Leetcode 22.括号生成 问题&#xff1a;数字 n 代表生成括号的对数&#xff0c;请你设计一个函数&#xff0c;用于能够生成所有可能的并且有效的括号组合。 算法&#xff1a; 创建返回数组 ans &#xff0c;和临时变量 path 。 当左括号数量 open 小于应填括号数 n 时&#…

【Python机器学习】NLP词中的数学——主题建模

目录 齐普夫定律 相关度排序 工具 其他工具 Okapi BM25 在文档向量中&#xff0c;词计数是有用的&#xff0c;但是纯词计数&#xff0c;即使按照文档长度进行归一化处理&#xff0c;也不能告诉我们太多该词在当前文档相对于语料库中其他文档的重要度信息。如果能弄清楚这些…

carla unreal engine源码:如何创建radar可视化探测锥

文章目录 前言一、C实现方法1、DrawDebugCone函数2、carla工程修改3、make launch4、探测锥验证 二、蓝图实现方法1、创建并打开蓝图2、打开蓝图事件图表3、绘制蓝图事件4、编译再运行 前言 1、在自动驾驶仿真调试以及测试过程中&#xff0c;我们经常会用到雷达的探测锥&#…

SkyWalking部署(监控系统)

简介 SkyWalking 是一个开源的应用性能监控 (APM) 和可观测性平台&#xff0c;旨在帮助开发者、运维人员和架构师监控、诊断和优化微服务架构中的应用。SkyWalking 提供了一套完整的工具链&#xff0c;用于收集、分析和可视化应用的性能指标、追踪和日志数据。 SkyWalking 的…