MySQL索引结构实例分析

简介

在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法。这种数据结构,就是索引

一般来说索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储的磁盘上。

优点:

1、类似大学图书馆建书目索引,提高数据检索的效率,降低数据库的IO成本。

2、通过索引列对数据进行排序,降低数据排序的成本,降低了CPU的消耗。

缺点:

1、虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。每次更新添加了索引列的字段,都会调整因为更新所带来的键值变化后的索引信息。

2、实际上索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录,所以索引列也是要占用空间的

索引举例:(用树结构做索引)

左边是数据表,一共有两列七条记录,最左边的是数据记录的物理地址。

MySQL索引结构实例分析

为了加快Col2的查找,可以维护一个右边所示的二叉查找树,每个节点分别包含索引键值和一个指向对应数据记录物理地址的指针,这样就可以运用二叉查找在一定的复杂度内获取到相应数据,从而快速的检索出符合条件的记录。

索引结构(树)

如何通过索引加快数据库表的查询速度呢?为了方便讲解,我们限定于数据库表只包含下面这样两个查询需求:

1、select* from user where id=1234;

2、select *from user where id>1234 and id<2345;(按区间)

为什么用树,而不用哈希表

哈希表按值查询的性能很好,时间复杂度是O(1),但它不能支持按照区间快速查找数据,因此无法满足要求。同理,尽管平衡二叉查找树查询性能很高,时间复杂度为O(logn),而且对树进行中序遍历,可以输出有序的数据序列,但也无法满足按照区间快速查找数据的需求。

为了支持按照区间快速查找数据,我们对二叉查找树进行改造,将二叉查找树的叶子节点用链表串起来,如果要查找某个区间的数据,只需要用区间的起始值,在树中进行查找,当定位到有序链表中的某个节点之后,再从这个节点开始顺着有序链表往后遍历,直到有序链表中的节点数据值大于区间终止值为止。

MySQL索引结构实例分析

又因为树上的很多操作的时间复杂程度与树的高度成正比,降低的树的高度,就能减少磁盘IO操作。因此我们把索引构建成m叉树(m>2),详细介绍可看后文。

BTree索引

在介绍B+树之前,先来了解一下B树。

MySQL索引结构实例分析

1、初始化介绍

一颗b树,浅蓝色的块我们称之为一个磁盘块,可以看到每个磁盘块包含几个数据项(深蓝色所示)和指针(黄色所示),如磁盘块1包含数据项17和35,包含指针P1、P2、P3。P1表示小于17的磁盘块,P2表示在17和35之间的磁盘块,P3表示大于35的磁盘块。

注意:

真实的数据只存在于叶子节点,即3、5、9、10、13、15、28、29、36、60、75、79、90、99。(而且是多条数据组成的数据区间:3~ 5,… … ,90~ 99)

非叶子节点不存储真实的数据,只存储指引搜索方向的数据项,如17、35并不真实存在于数据表中。

2、查找过程

如果要查找数据项29,那么首先会把磁盘块1由磁盘加载到内存,此时发生一次IO,在内存中用二分查找确定29在17和35之间,锁定磁盘块1的P2指针,内存时间因为非常短(相比磁盘的IO)可以忽略不计,通过磁盘块1的P2指针的磁盘地址把磁盘块3由磁盘加载到内存,发生第二次IO,29在26和30之间,锁定磁盘块3的P2指针,通过指针加载磁盘块8到内存,发生第三次IO,同时内存中做二分查找找到29,结束查询,总计三次IO。

B+Tree索引

B+树和B树类似,B+树是B树的改进版。 即:m叉查找树与有序链表构建成的树就是B+树,也就是要存储的树索引

MySQL索引结构实例分析

如图:B+树和B树的主要区别有以下两点:

1、B+树的叶子节点用链表来串联。 查找某个区间的数据,只需要用区间的起始值,在树中进行查找,当定位到有序链表中的某个节点之后,再从这个节点开始顺着有序链表往后遍历,直到有序链表中的节点数据值大于区间终止值为止。

2、B+树中的任何节点都不存储真实数据,只是用来索引。 B树直接通过叶子节点获取到数据;而B+树每个叶子节点存储数据行的键值和地址信息,当查询到某个叶子节点时,通过叶子节点的地址找到真实的数据信息。

聚簇索引与非聚簇索引

聚簇索引并不是一种单独的索引类型,而是一种数据存储方式。 术语‘聚簇’表示数据行和相邻的键值聚簇的存储在一起。

聚簇索引的好处:

按照聚簇索引排列顺序,查询显示一定范围数据的时候,由于数据都是紧密相连,数据库不不用从多个数据块中提取数据,所以节省了大量的io操作。

聚簇索引的限制:

1、对于mysql数据库目前只有innodb数据引擎支持聚簇索引,而Myisam并不支持聚簇索引。

2、由于数据物理存储排序方式只能有一种,所以每个Mysql的表只能有一个聚簇索引。一般情况下就是该表的主键。

3、为了充分利用聚簇索引的聚簇的特性,所以innodb表的主键列尽量选用有序的顺序id,而不建议用无序的id,比如uuid这种。

如下图,左侧的索引就是聚簇索引,因为数据行在磁盘的排列和索引排序保持一致。

MySQL索引结构实例分析

索引分类

单值索引

即一个索引只包含单个列,一个表可以有多个单列索引

随表一起建索引:CREATE TABLE customer (id INT(10) UNSIGNED  AUTO_INCREMENT ,customer_no VARCHAR(200),customer_name VARCHAR(200),PRIMARY KEY(id),KEY (customer_name)); 单独建单值索引:CREATE  INDEX idx_customer_name ON customer(customer_name);  删除索引:DROP INDEX idx_customer_name  on customer;

少数索引

索引列的值必须少数,但允许有空值

随表一起建索引:CREATE TABLE customer (id INT(10) UNSIGNED  AUTO_INCREMENT ,customer_no VARCHAR(200),customer_name VARCHAR(200),  PRIMARY KEY(id),  KEY (customer_name),  UNIQUE (customer_no));  单独建少数索引:CREATE UNIQUE INDEX idx_customer_no ON customer(customer_no);  删除索引:DROP INDEX idx_customer_no on customer ;

主键索引

设定为主键后数据库会自动建立索引,innodb为聚簇索引

随表一起建索引:CREATE TABLE customer (id INT(10) UNSIGNED  AUTO_INCREMENT ,customer_no VARCHAR(200),customer_name VARCHAR(200),  PRIMARY KEY(id) );   CREATE TABLE customer2 (id INT(10) UNSIGNED   ,customer_no VARCHAR(200),customer_name VARCHAR(200),  PRIMARY KEY(id) );  单独建主键索引:ALTER TABLE customer  add PRIMARY KEY customer(customer_no);   删除建主键索引:ALTER TABLE customer  drop PRIMARY KEY ;   修改建主键索引:必须先删除掉(drop)原索引,再新建(add)索引

复合索引

即一个索引包含多个列

随表一起建索引:CREATE TABLE customer (id INT(10) UNSIGNED  AUTO_INCREMENT ,customer_no VARCHAR(200),customer_name VARCHAR(200),  PRIMARY KEY(id),  KEY (customer_name),  UNIQUE (customer_name),  KEY (customer_no,customer_name)); 单独建索引:CREATE  INDEX idx_no_name ON customer(customer_no,customer_name);  删除索引:DROP INDEX idx_no_name  on customer ;

性能分析

索引创建场景

哪些情况需要创建索引

1、主键自动建立少数索引

2、频繁作为查询条件的字段应该创建索引

3、查询中与其它表关联的字段,外键关系建立索引

4、单键/组合索引的选择问题, 组合索引性价比更高

5、查询中排序的字段,排序字段若通过索引去访问将大大提高排序速度

6、查询中统计或者分组字段

哪些情况不要创建索引

1、表记录太少

2、经常增删改的表或者字段 原因:提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件

3、Where条件里用不到的字段不创建索引

4、过滤性不好的不适合建索引

感谢各位的阅读,以上就是“MySQL索引结构实例分析”的内容了,经过本文的学习后,相信大家对MySQL索引结构实例分析这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

文章标题:MySQL索引结构实例分析,发布者:亿速云,转载请注明出处:https://worktile.com/kb/p/22250

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
亿速云的头像亿速云认证作者
上一篇 2022年9月1日 下午11:17
下一篇 2022年9月1日 下午11:18

相关推荐

  • 如何进行Linux恶意软件SkidMap分析

    挖掘加密货币恶意软件仍然是一个普遍的威胁。网络罪犯也越来越多地探索新的平台和方法来进一步利用挖矿恶意软件——从移动设备、Unix和类Unix系统到服务器和云环境。 攻击者不断提升恶意软件抵御检测的能力。例如,将恶意软件与看门狗组件捆绑在一起,以确保非法的加密货币挖掘活动在受感染的机器中持续存在,或者…

    2022年9月20日
    60600
  • mysql函数的作用有哪些

    mysql函数的作用是用来实现某些功能运算和完成各种特定操作;使用函数能够允许标准组件式编程,提高了SQL语句的重用性、共享性和可移植性,可以减少重复编写程序段的工作量,提高程序的可读性,提高程序编译和运行效率,产生质量较高的目标代码。 本教程操作环境:windows10系统、mysql8.0.22…

    2022年9月6日
    48000
  • win7如何清理微信和qq缓存

    win7清理微信和qq缓存的方法 微信清理: 1、打开微信,点击左侧下方三条横杠,打开后点击“设置” 2、 点击“通用设置” 3、点击右侧的“存储空间管理” 4、找到缓存这里,点击对应的管理和清理就可以了。 QQ缓存清理: 1、打开QQ主面板,点击左下方三条杠,点击“设置” 2、点击左边的“文件管理…

    2022年9月24日
    42300
  • ftp服务器搭建部署与C#实现ftp文件上传的方法是什么

    一、简介 FTP是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为“文本协议”。用于Internet上的控制文件的双向传输。同时,它也是一个应用程序(Application)。基于不同的操作系统有不同的FTP应用程序,而所有这些应用程序都遵守同一种协议以传输文件。…

    2022年9月15日
    73400
  • how2heap注意点有哪些

    first-fit 我的理解是分割unsortedbin里面名列前茅个大于要分配的chunk,但是实际上并不是这样 测试程序 #include <stdio.h>#include <stdlib.h>#include <string.h>int main(){ i…

    2022年9月15日
    38700
  • mysql如何查询临时表

    本教程操作环境:windows7系统、mysql8版本、Dell G3电脑。 mysql临时表 在MySQL中,临时表是一种特殊类型的表,允许您存储临时结果集,您可以在单个会话中多次重复使用。 当查询需要带有JOIN子句的单个SELECT语句的数据是不可能或非常耗时,临时表非常方便。在这种情况下,您…

    2022年9月26日
    1.1K00
  • SpringBoot统一返回格式怎么实现

    1. 直接返回结果 先看一下最基本的例子,直接将结果原封不动返回: @Data@AllArgsConstructor@JsonIgnoreProperties(ignoreUnknown = true)public class TestVo { private static final long s…

    2022年8月31日
    55000
  • win11更新后没声音怎么解决

    win11更新后没声音解决方法: 方法一: 1、部分设备在win10上的驱动可能无法在win11使用。 2、所以可以尝试拔出耳机或音效后,重新连接一下试试看。 方法二: 1、如果重新插拔后还是不行。 2、那么推荐下载一个Realtek音频管理器。【点击下载】 3、下载安装好之后,在其中开启声音就可以…

    2022年9月13日
    95200
  • mysql如何查询第几条数据

    查询第几条数据的方法:使用SELECT语句配合LIMIT子句来查询,语法“SELECT *|字段名列表 FROM 表名 LIMIT 初始位置,记录数;”或“SELECT *|字段名列表 FROM 表名 LIMIT 记录数 OFFSET 初始位置;”。LIMIT子句可指定查询结果从哪条记录开始显示,显…

    2022年9月22日
    1.0K00
  • 数据库mdf文件怎么打开

    数据库mdf文件打开方法: 1、找到要打开的数据库文件。 2、用sql server进行打开。 3、开启后点击“连接”。 4、进入管理页面。 5、右击数据库选择“附加”功能。 6、进入“附加数据库”。 7、点击“添加”选择要附加的数据库。 8、选中添加数据库点击“确定”。 9、开启后就可看到所有数据…

    2022年9月8日
    2.4K00
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部