Mysql--技术文档--索引-《索引为什么查找数据快?》-超底层详细说明索引

索引的概念 

在MySQL中,索引是一种数据结构,它被用于快速查找、读取或插入数据。索引能够极大地提高数据库查询的速度。

索引的工作方式类似于图书的索引。如果你想在图书馆找到一本书,你可以按照书名进行查找。书名就像是一个索引,它可以快速引导你找到正确的书籍。在数据库中,索引也是同样的作用。

索引在MySQL中的作用主要有以下几点:

  1. 加速查询:当对数据库进行查询时,MySQL可以通过索引快速定位到需要的数据,而不需要扫描整个数据库。
  2. 排序:如果查询需要按照某个字段进行排序,索引可以提高排序的效率。
  3. 分组(GROUP BY):当使用GROUP BY子句时,索引也可以提高分组的速度。
  4. 限制结果集:索引可以过滤掉不需要的数据,从而减少需要返回的数据量。

需要注意的是,虽然索引可以提高查询速度,但是它也有一些负面影响。例如,索引需要占用存储空间,并且在插入、更新、删除数据时,由于需要维护索引,可能会导致一些性能开销。因此,在设计数据库时,需要根据实际情况来决定是否需要创建索引,以及在哪些字段上创建索引。

计算机中磁盘的扇区与磁道--前提

Mysql--技术文档--索引-《索引为什么查找数据快?》-超底层详细说明索引_第1张图片

        扇区,是指磁盘上划分的区域。磁盘上的每个磁道被等分为若干个弧段,这些弧段便是磁盘的扇区,硬盘的读写以扇区为基本单位 

        Mysql--技术文档--索引-《索引为什么查找数据快?》-超底层详细说明索引_第2张图片

        其实就是一个磁盘被一个一个同心圆划分为一个个磁道。一个个磁道被分割为一个个扇区,也就是说在这里面的绿色的就是一个扇区。

        通常一个扇区可以存储可以存放512个字节的信息,磁盘驱动器在向磁盘读取和写入数据时,要以扇区为单位。

索引的核心--减少磁盘io

磁盘io的效率是很慢的

磁盘io是计算机系统中慢的一项工作,所以它会花费大量的时间。这是因为磁盘io操作的性能取决于它的物理结构,而物理结构受到了一些限制。

磁盘io操作的物理操作

磁盘Io操作受到物理限制,因为磁盘是一个物理磁盘,它有一个机械部件,它是由一个电机驱动的这个电机负责把磁盘上的数据读取到内存中。电机的转速越快,磁盘的io性能就越好。但是由于电机的机械特性,它的转速是有限的,所以它的性能也有限。

所以如何快速有效的让磁盘找到对应的物理地址,就是索引的重要概念

索引的底层以及实现机制 

通过图示和计算来讲述和说明数据!!!!!!

我们看一下一条数据是多大--在mysql中

示例表 t_demo

Mysql--技术文档--索引-《索引为什么查找数据快?》-超底层详细说明索引_第3张图片Mysql--技术文档--索引-《索引为什么查找数据快?》-超底层详细说明索引_第4张图片

那么我们可以根据每个字段的大小判断出这个表中的一条数据是多大。

计算过程为:

这个表中的一条数据的大小取决于具体的数据。为了计算每列的大小,我们需要知道每个列的数据类型和长度。

对于 id 列,它是一个 int 类型,通常占用 4 个字节。

对于 name 列,它是一个 varchar 类型,长度可以根据具体情况变化。如果最大长度为 25,那么平均每个字符的字节数取决于具体的字符集。UTF-8 字符集通常占用 1 到 4 个字节。所以,如果平均每个字符为 2 个字节(这是一个常见的估算值),那么 name 列的平均大小为 50 个字节。

对于 sex 列,它是一个 int 类型,通常占用 4 个字节。

对于 phone 列,它也是一个 varchar 类型,长度可以根据具体情况变化。如果最大长度为 25,那么平均每个字符的字节数也取决于具体的字符集。如果平均每个字符为 2 个字节,那么 phone 列的平均大小为 50 个字节。

所以,一般来说,一条数据的大小大约在 58 到 108 个字节之间,具体取决于 name 和 phone 列的实际字符长度。

每个属性的具体大小如下:

  • id: 4 bytes
  • name: 可变长度,取决于实际字符长度。平均每个字符占用 2 个字节,所以平均大小为 2 * length。
  • sex: 4 bytes
  • phone: 可变长度,取决于实际字符长度。平均每个字符占用 2 个字节,所以平均大小为 2 * length。

注意:是一种估算方法,具体大小取决于实际情况,包括具体的值和字符集等。

示例的一条记录:

Mysql--技术文档--索引-《索引为什么查找数据快?》-超底层详细说明索引_第5张图片

当然:电话号不是真的

INSERT INTO `day1`.`t_demo` (`id`, `name`, `sex`, `phone`) VALUES (1, '阿丹', 1, '16668066369');

这条记录的大小为:

  • id: 4 个字节
  • name: '阿丹' 两个字符,使用 UTF-8 编码,每个字符占用 3 个字节,所以 '阿丹' 占用 6 个字节
  • sex: 1 个字节
  • phone: '16668066369' 11个字符,使用 UTF-8 编码,每个字符占用 3 个字节,所以 '16668066369' 占用 33 个字节

所以,这条记录总共占用 4 + 6 + 1 + 33 = 44 个字节。

其次就可以计算出一个扇区可以存放多少条这样的记录

计算过程为:

一个扇区是可存放512个字节。并且一次磁盘的Io是以扇区为单位的,也就是说如果读取了三个字节就是发生了三次io。

一个扇区内可存放记录为:

512/44=11.6363636364

可以计算得出一个扇区可以存储11个记录。

那么如果此时整张表格需要存储10000(一万条数据)计算可得需要的字节内存为

44*10000=440000字节

这个时候我要将这些数据存放到多少个扇区?

440000/512=859.375

也就说如果查找的是在表中的最后一条数据的话就要去发生859次io来将指针移动到我们需要查找的数据这里。

所以为了减少io索引的概念出现了。

索引表

表结构简单,指向单个记录的地址。

在MySQL中,物理地址的数据类型取决于存储引擎和数据表的实现方式。一般来说,物理地址可以是整数类型(INT)或长整型(LONG),具体取决于存储引擎和数据表的设置。

对于InnoDB存储引擎,物理地址通常存储在系统表中的某个列中,例如"FIL_PAGE_ADDR"。对于InnoDB的B-tree索引,每个索引项的大小取决于所存储列的类型和长度。例如,如果索引列是整数类型(INT),则每个索引项的大小为4字节。

索引表的作用主要是为了提高数据查询效率,而不是记录的物理地址。索引表会根据特定的列(例如主键)对数据进行排序,并在每个记录中存储相应的物理地址。当执行查询时,MySQL可以通过索引表快速定位到所需的数据,而不必扫描整个表。

索引表可以是基于B-tree(B树)或哈希表等数据结构实现的。在B-tree索引中,每个节点包含键值和相应的物理地址。根据键值在树中进行二分查找,可以快速找到相应的记录。

然而,不同的存储引擎对索引的实现方式可能会有所不同。例如,InnoDB存储引擎支持聚集索引(聚集在物理上的索引),这意味着表中的数据按照一定顺序存储,并且主键索引可以直接提供物理地址。而MyISAM存储引擎则使用非聚集索引,这意味着索引和数据存储在不同的文件中,需要通过索引获得中间结果集,然后再根据结果集中的记录再回表获取对应的实际数据。

总之,索引表主要用于提高查询效率,它存储的是记录的键值和相应的物理地址,而不是记录的全部信息。

Mysql--技术文档--索引-《索引为什么查找数据快?》-超底层详细说明索引_第6张图片

那么关于mysql中的其他索引

在MySQL中,索引和索引表是两个不同的概念。索引是一种数据结构,用于快速查找表中的数据,而索引表则是存储索引的一种物理结构。

对于主键索引,主键通常是记录的唯一标识符,即记录的Id。在InnoDB存储引擎中,主键索引是默认创建的,当你在创建表时指定了主键列,InnoDB会自动创建一个基于该列的B-tree索引。主键索引中存储的是主键列的值和相应的物理地址。

对于其他索引,它们是基于表中的其他列创建的。这些索引中存储的是该列的值和相应的物理地址。与主键索引不同的是,这些索引可能包含部分或全部表的数据,因此它们的大小可能会比主键索引大。

总之,在MySQL中,索引和索引表是两个不同的概念。主键索引是基于主键列创建的,而其他索引则是基于表中的其他列创建的。无论哪种类型的索引,它们都存储了相应的物理地址,用于快速定位到所需的数据。

也就说更换的是上图中的索引表中的主键也就是id,更换为这个表中的其他值。

比如我要根据name进行索引,我对这个列添加了所以那么

Mysql--技术文档--索引-《索引为什么查找数据快?》-超底层详细说明索引_第7张图片

那为什么索引会快?

        如果你的主键是int类型,通常会占用4个字节。对于该索引表中记录物理地址的long类型列,一般会占用8个字节。也就是说,在这种情况下,一条记录通常会占用12个字节(4个字节主键 + 8个字节物理地址)。请注意,这只是一个简单的估计,实际的存储空间可能会受到MySQL的存储引擎以及其他因素的影响!

        那么我们可以计算一下如果我们根据这个主键的索引表来查找数据会减少多少次io

        首先一个扇区可以存放的索引表数据条数

        512/12=42.6666666667

42条数据比之前的表中只能存放11条多了31将近三倍。

        要查找10000条的io次数为:

        12*10000/512=234.375

        可以看到使用了主键索引来查找遍历10000条数据的io次数为234比上面的859少了很多。当然这只是仅仅使用了主键索引,在mysql中还有B+树作为数据结构、以及二级索引还会更快。

        核心减少了io次数!!!

mysql中的索引 

MySQL支持多种索引类型,包括B-tree索引、哈希索引、位图索引等。具体支持的索引类型取决于所使用的存储引擎。

以下是一些常见的MySQL存储引擎和它们支持的索引类型:

  1. InnoDB存储引擎:支持B-tree索引和哈希索引。
  2. MyISAM存储引擎:支持B-tree索引,但不支持哈希索引。
  3. MEMORY存储引擎:支持哈希索引和B-tree索引。
  4. MERGE存储引擎:不支持独立的索引,而是通过组合多个MyISAM表中的B-tree索引来实现索引功能。
  5. FEDERATED存储引擎:不支持独立的索引,而是通过访问远程MySQL服务器上的表来实现索引功能。

其中特殊索引为:

聚合索引是一种特殊类型的索引,它用于加速对数据库表中的数据进行查询。

在MySQL中,聚合索引是基于表的某个列或多个列的值进行创建的。它可以将数据按照索引列的值进行排序,并存储在索引结构中,从而加速查询。

聚合索引对于查询性能的提升非常显著,特别是对于那些经常被查询的列。它能够大大减少查询时需要访问的数据量,从而提高查询效率。

在InnoDB存储引擎中,默认情况下会创建一个名为"PRIMARY"的聚合索引,该索引基于主键列创建。此外,用户也可以手动创建额外的聚合索引。

需要注意的是,聚合索引的创建和维护都需要消耗一定的存储空间和计算资源。因此,在选择要创建聚合索引的列时,需要仔细考虑列的选择是否能够带来足够的查询性能提升,并权衡其开销和收益。

另外,"PageRank"是Google公司为Web页面设计的专利算法,它通过分析Web页面之间的链接关系来确定每个页面的重要性。在MySQL中,没有直接使用"PageRank"算法的聚合索引,但可以通过其他方法实现类似的功能。

除了聚合索引,MySQL还支持其他一些特殊类型的索引,包括:

  1. 全文索引:用于在文本搜索中加速查询。MySQL提供了两种全文索引类型,即MyISAM和InnoDB引擎支持的全文索引。全文索引主要用于基于单词或短语在文本块中的位置进行搜索。
  2. 空间索引(Spatial Index):也称为R-tree索引,用于加速空间数据的查询。空间索引主要应用于地理位置数据类型,如点、线、多边形等。
  3. 哈希索引(Hash Index):基于哈希算法实现的索引,主要用于等值查询。哈希索引适用于等值查询,但对于范围查询和排序查询等操作效率较低。
  4. 位图索引(Bitmap Index):是一种特殊的位图数据结构,用于表示一组数据中某些元素是否存在。位图索引适用于具有大量唯一值的列,如性别、学历等。

需要注意的是,这些特殊类型的索引在MySQL中并不是所有存储引擎都支持的。例如,全文索引和空间索引仅在MyISAM和InnoDB存储引擎中支持。在使用这些特殊类型的索引时,建议参考MySQL官方文档以了解更多详细信息和特定存储引擎的限制。

拓展/注意:

        本文章看完之后可以看到,就算引入了索引表的概念,但是终归还是一个表。还是要找到一个地方去进行存储。那就还是有多次Io的问题(在数据量大的情况下)。

        于是就引入了数据结构树的概念。

你可能感兴趣的:(mysql,mysql,数据库)