数据库索引的底层原理--索引为什么快?

说实话,刚开始学索引的时候让我很头疼。
它就像一本书的目录。
您不必一页一页地搜索信息,可以直接进入相应的章节。
这同样适用于数据库。
索引使查询更快。

给我印象最深的是MySQL中的测试。
一旦索引被添加到用户的表中。
该表原本包含数十万条数据。
在不添加索引的情况下,找到特定用户需要多少秒?添加索引后?以毫秒为单位返回。
我当时就想知道发生了什么事。

索引的底层主要由两类树组成,BTREE和B+TREE。
我对BTREE的理解是每个节点都存储数据,而B+TREE只存储叶子节点上的完整数据,非叶子节点作为路径。
为什么B+TREE这么快?因为它压缩了叶子节点中的所有数据,所以叶子节点之间有连接的指针。
如果搜索一条数据,就可以顺着线索找到一条数据。
这就像检查高考成绩一样。
B+TREE类似于文本验证。
您可以转到该页面并直接查看所有结果。
BTREE就像查字典一样。
你必须一页一页地往下才能找到该页。

有趣的是MySQL中的InnoDB和MyISAM处理索引的方式非常不同。
InnoDB索引直接将数据填充到叶子节点中,通过搜索索引值就可以直接获取数据。
这称为聚集索引。
在MyISAM中,索引存储的是数据的地址,你必须通过地址才能找到原始数据。
这称为非聚集索引。
我测试过,发现使用InnoDB表,范围查询非常快。
使用 MyISAM 表?检查一条数据还好,但检查一组连续的数据就慢了。

所以,说到索引,不要只看概念。
您确实需要运行代码并了解 BTREE 和 B+TREE 如何使用数据。
例如,您可以使用 EXPLAIN 命令检查 SQL 语句,了解它的索引方式、叶节点在哪里以及返回什么数据。
在过去的几年里,我帮助人们配置数据库,发现很多人从来没有见过索引页是什么样子的。
仅仅依靠理论当然是不可能的。

我记得数据是关于X的,但我建议你检查一下实现细节指定数据库的当前版本。
不管怎样,我已经做了十年了,我觉得光看索引理论是没有意义的。
您必须用手触摸索引页才能知道它是如何工作的。

MySQL学习-深入理解索引底层原理

索引……这个太重要了。
2 02 2 年我会思考这个问题。
MySQL的索引不是一个单一的东西。
方法、类型、存储引擎和字段数量都清晰分开。

首先我们来谈谈Hash索引。
这个东西底层就是一个哈希表。
搜索速度很快,只需几秒钟即可找到类似的值。
我一直在尝试使用哈希索引来检查具有数万位数据的表中的主键。
它非常快。
但它有一个致命的缺陷,范围查询不能做到这一点。
想要查找所有大于某个值的数据?哈希索引是愚蠢的。
另外,当数据过多时,会出现冲突问题,链表看起来扭曲,查询效率下降。
所以现在很少使用Hash索引了。
基本上都是InnoDB这样的覆盖索引,或者Memcached这样的内存数据库,不使用磁盘,冲突问题并不突出。

我们来谈谈BTree索引。
这是 MySQL 的主力。
B-Tre和B+Tre,最常见的是B+Tre。
那么B树呢?它是一个平衡的多树。
每次搜索数据时,磁盘 I/O 都会最小化,因为磁盘读取速度比内存慢得多。
B+Tree在B-Tree的基础上做了一个很大的创新,就是数据有叶子节点,索引和数据融为一体。
查询时,查完索引后,直接到叶子节点去检索数据,不需要跑回表。
我已经尝试过了。
对于同一个查询,有B+Tree索引和没有B+Tree索引的差别可能只有几毫秒,有时甚至十几毫秒。
但是当数据量太大时,BTree的高度会很高,逐层检查相当繁琐。

那么MyISAM和InnoDB引擎的索引是有很大不同的。
MyISAM 的索引与数据是分离的。
它有一个叫做非聚集索引的东西,也就是银行地址。
此类索引适合单列查询和快速定位。
但不支持区域查询。
如果查询所有大于某个值的记录,MyISAM 就会卡住。
InnoDB 则不同。
索引和数据组合在一起,称为聚集索引。
主键是聚集索引的键,数据驻留在叶子节点中。
如果没有主键,InnoDB会自动为你生成一个。
这些自动生成的内容有时会占用大量空间并会影响性能。
我见过那种表,没有主键,InnoDB自动生成6 字节ID,查询效率慢。

单值指数和通用指数也必须分开讨论。
单值索引是每个字段一个索引。
联合索引是将多个字段组合成一个索引。
普通索引有一个“最左前缀”,这意味着搜索时,匹配应该从最左边的字段开始。
例如,如果您有一个索引 (a, b, c) 并且您检查 WHERE a = 'value',它将起作用。
如果您检查 WHERE b = 'value',它将起作用,但如果您检查 WHERE c = 'value',它将不起作用,因为 c 不在左侧。
我以前也遇到过这种情况,所以写SQL的时候一定要小心。

最新的覆盖指数非常棒。
即查询所需的数据直接存储在索引中,不需要返回表查找数据。
例如,如果查询 SELECT name FROM users WHERE id = 1 00;,如果有索引(id, name),则该查询可以直接从索引中检索名称,而无需查表。
这种类型的索引非常高效,数据库根本不需要读取实际的数据页。

总之,一旦理解了索引,SQL查询的性能就可以得到显着的提高。
深入理解MySQL索引和数据库性能调优就是那些真正的技能。
但如果您只是说说而已,那么下一步就是学习Explain命令,看看查询是如何执行的,以便能够对其进行微调。

深入解析mysql中的索引(原理详解)

错误如下:不要在 InnoDB 中使用 UUID 作为主键;这会增加分页的可能性。
不要:使用联合标签时;不违反最左优先规则;否则,索引将会失败。
Don't believe it: Don't use non-query columns after a range query.否则,联合索引将会失败。
实用提醒:设计索引时,先分析查询结构,避免不必要的索引。

MySQL中有多少种索引?索引的底层实现原理是?

这就是陷阱:过多的索引会降低写入性能。

不信:全文索引默认不支持中文搜索。

不要:不要在非搜索字段上创建索引。