10年专注安防设备研发产品质量有保 售后7×24小时服务
24小时咨询热线:4006666666
联系我们
安防设备有限公司
全国免费服务热线:4006666666
地址 :中国·北京
联系人:
您的位置: 首页>>热门话题>>正文
热门话题

在学习覆盖索引之前,我们需要知道什么是返回表操作(什么是覆盖索引和回表)

时间:2023-02-23 作者:admin666ss 点击:33次

提前注意:

索引是按一定顺序存储数据的数据结构。

字典结构:

当我们拿一本汉语词典时,我们会将词典的结构分为两部分,一部分是目录,另一部分是内容部分。

拼音搜索:

当我们想查找单词“T”时,我们去D_part查找拼音中汉字“gun”的页码。如果D_ part中不存在,则表示词典中不存在单词“”。另一方面,如果您通过拼音“gun”在D_part中找到单词“t”,则可以使用在D_ part中标记的单词的页码快速定位C_part中的单词“t”。

在这个过程中,我们按照字母az的顺序快速地将G定位在D_。在无数的汉字中,不仅D_ part根据AZ排序,C_part也根据A~Z排序,这就是有序拼音搜索。

总之,D_ part和C_。

侧边搜索:

当我们查找“应该”这个词时,我们不知道这个词的拼音。此外,我们不能像拼音搜索那样通过A~z顺序进行搜索,只能将相同类型的部分汉字收集到一个集合中,并在D_part中列出它们。同时,C_ part中相同两个字符的位置,可能是“天涯”中的一个,也可能是“海角”,也就是说,一个可能在第1页,另一个在第999页。也可能是两个字符紧挨着,都在第100页。

例如,相同的部分“开”、“开”和“清”,即发音为{kǎi462iqing}。“Kai”和“Kai”不仅在同一面,而且发音也相同,那么这两个词,可能在第100页,而“love”一词可能在最后一页。

一个简单的总结:D_part通过一组相同的字符在侧边用作有序目录索引,而C_part不按侧边排序,甚至可能随机分布。

聚集索引和非聚集索引

好的,理解了上述抽象概念,我们开始将上述概念与实际的物理硬盘文件对应起来。

假设我们首先创建两个文件,一个索引。文件和数据。文件分别对应于D_ part和C_。

并对索引中的所有内容进行排序。文件的顺序为0到9。

① 聚集索引

定义-数据行的物理顺序与列值的逻辑顺序相同,一个表中只能有一个聚集索引。

既然这是一对一的通信,为什么我们不能将两个文件合并成一个呢 即:

这种将索引文件与具体数据文件直接放置在一起的结构称为聚集索引。因为通过索引可以直接获得具体数据。但只有当它们以特定的顺序存储时,我们才能直接合并它们,否则,如果它们无序,以这种方式编制索引只会让人更加混乱。

请注意,定义中说:一个表只能有一个聚集索引。为什么 由于这是按某种顺序排列的,因此该顺序只能是唯一的。就像数字091099…这个顺序是唯一的,所以一个表只能有一个聚集索引

② 非聚集索引

定义-此索引中索引的逻辑顺序不同于磁盘上行链路的物理存储顺序,一个表可以有多个非聚集索引。

根据定义,并与按边索引类似,字典D_part的内容是按规则顺序排列的不同边的集合,但C_part的位置可能令人混淆。通过这种方式,我们映射到一个文件。虽然索引中包含索引。文件排列整齐,我们索引之间的对应关系。文件和数据。文件将感到困惑,即。

然而,没有办法合并索引。文件和数据。文件转换为单个文件,就像我们处理聚集索引一样。为了讨论原因,我们必须将表合并到数据库中。

数据中的内容。文件实际上是数据库中的一个表,该表有两个字段:索引和数据。如果此表中的索引字段是随机生成的主键,则不会从头到尾排序。

所以如果是数据。文件和索引。文件要合并到同一个文件中,可以是索引中的索引字段。文件顺序错误,或数据中的数据字段错误。文件坏了。如果数据字段的顺序不正确,则数据库中表的顺序将直接更改,因此不要这样做。如果索引中有索引字段。文件无序,这违背了目的,因为索引确实用于快速查找数据。这就好像字典里的目录很混乱,你怎么能查到汉字呢

请注意,该定义指出一个表可以有多个非聚集索引。为什么 与聚集索引相比,索引和数据。聚集索引的文件是按顺序排列的,因此只能有一个聚集索引,但数据中的数据除外。非聚集索引指向的文件无序,因此它不受顺序规则的限制,可以有多个非聚集索引

3 面纱:

Myi:MYisam索引

Myd:MYisam数据

Ibd:InnoDB数据

让我们从官方定义开始:

通常,如果要查找没有索引的记录,mysql必须从第一行开始,然后通读表以查找相关行。表中的行越多,花费的时间越长。通过索引,mysql可以使用索引快速确定在数据文件中查找数据的位置,而无需遍历整个表。

目前,您可能想知道为什么索引可以快速定位数据,但尚未介绍索引的结构,稍后您将了解索引的底层结构。可以说,虽然索引可以有R-TreeHashb-tree等数据结构所表示的各种形式的逻辑结构,但由于B+树的优秀搜索特性满足了索引的需要,所以通常多采用B+树结构。

为了理解:

当您查看官方定义时,您知道索引很快就能定位,但是当您将两个图与聚集索引结合起来时,您可能会觉得索引没有太大不同。

想想看,如果要查找一个有数千万行的表,并且每次都要遍历整个表一次,那将是多么可怕。因此,虽然您可能认为索引本身就是遍历,但您可能认为这就像遍历整个表,但您只是不知道索引是如何工作的。我们需要知道的是,索引的大部分底层结构都是B+树,但忘记B+树是如何让索引快速查找的。

[新闻早知道]

现在,知道B+树可以做到这一点就足够了。

创建语法

创建表时直接指定。

创建索引将普通索引或唯一索引添加到现有表中。

Alter表语法

删除索引

①B+树是一种多叉自平衡搜索树,是B-树的变种。

由于B+树是从B-树演化而来的搜索结构,因此在学习B+树之前,应了解以下知识。

二叉树二叉搜索树平衡二叉树平衡多路径搜索树

B+树是B-树的变体。B+树和B-树的区别是:

非叶节点仅存储键值信息。

所有数据记录都存储在叶节点中

这些叶子通过双向指针相互链接,因此它们可以快速横向访问其他叶子

如图所示,根节点不存储数字1000,而是将自身划分为n个区间,这些区间被划分为三个区间,即,非叶节点的所有子节点也是如此。最重要的一点是,所有具体数据都存储在叶节点中。

例如,如果我们想找到数字1000,我们只需要根据每个节点的间隔输入数字1000存在的间隔,直到存储数据的叶节点。

步骤:

C步骤:

1 准备

为了解释mysql中的B+树索引,我们必须使用数据库表进行实际操作。

我不知道您是否记得InnoDB使用聚集索引,因此下面的索引结构将是聚集索引。

A: 首先,您必须创建一个数据库表

B: 插入一些数据:

② 启动过程

指数总体结构图如下:

D: 假设我想找到一个user_ id范围从2到6的用户

E: 最后,我们在索引中直接找到user_ id为2到6的用户信息。

③ 思维的简单延伸

上面的示例可能很简单,但它显示了B+树在查找数据方面的优势。例如,我们的数据有数百万行,user_id不是主键因此InnoDB不会自动将user_id设置为主键索引。当我们需要查找数据时,可以通过索引快速定位要查找的行,甚至通过B+树叶子节点的双向指针前后移动。而不是逐行比较原始user_表中每行的user_。

4 比较

根据上面的图表和说明,我们了解了B+树的一般结构和索引的一般过程。为了巩固上述概念,让我们开始新一轮的比较。

比较是否存在索引之间的差异。

无索引:

有一个索引:

例如,我们分配相同的叶节点,其中user_name以A开头,另一个叶节点的user_。

如果我们需要这样做,我们可以通过索引快速找到用户名以C开头的用户的信息。

有趣吗 在B+树结构的支持下,我们只需要比较几次结果,因此即使数据量很大,我们也不必担心查询数据所需的时间。

然而,也有利弊,我们将在未来的一节中专门讨论索引的利弊。

上面提到了InnoDB的聚集索引,这说明索引文件和数据文件存储在同一个文件中。还提到了MyISAM的非聚集索引,它解释了索引文件与数据文件是分开的。您可能仍然感到困惑,但请比较以下两个逻辑图以大致了解差异。

在前一篇文章中,使用索引的好处已经重复了好几次,都是关于“加速查询”的主题。因为它重新排序了设置为索引的字段,并将它们存储在其他地方,而不影响原始表。每次查询字段时,直接进入规则有序的索引文件进行查询,而不是进入混沌无序的原始表进行查询,大大缩短了搜索时间。

存储空间大小:

从MyISAM的非聚集索引开始:我们知道如果我们不创建索引,我们只有一个*。myd文件,仅用于存储表中的数据。当我们创建索引时,我们有一个*。存储索引本身的myi文件。

因此,我们需要考虑索引文件本身占用的存储大小。如果查看索引文件的大小,它会占用相当多的空间。如果有数千万行数据,那么这个索引文件的存储成本一定不小。因此,当为一个表创建太多索引时,很容易耗尽磁盘空间。因此,在创建索引时应适当考虑。

SQL语句执行速度

我们一直在谈论索引有多好,但这总是相对于“选择”查询。假设我们想更改表中用户的数据。例如

想象一下,当我们没有索引,需要更改100000行时,所需时间与“更改100000行”所需时间完全相同。然而,如果我们添加了一个索引,除了表中的100000行之外,我们还需要更改索引中的100000个行。

假设更新有点良心,因为它至少不涉及索引顺序。但是插入物呢 删除 这两个操作都直接影响索引排列结构,例如删除中间的N个数据;或者在中间插入N个数据,节点达到最大存储数据,则整个索引的全局顺序或多或少会受到影响。

小结

因此,虽然索引可以帮助我们快速查找数据,但CRUD中的CUD很困难。索引应应用于那些更经常查询的表,而不应尽可能添加那些经常更改和删除的表。

至于存储空间,如果业务需要使用索引进行优化,请考虑增加存储空间,这不是什么大问题。

唯一的索引

它与普通索引类似,只是索引列的值必须唯一,但允许空值。

概念:索引包含一个字段,索引排序仅对该字段排序。一个表可以同时具有多个单值索引。

到目前为止,引入的索引是单值索引,例如仅为user_id字段或user_name字段创建索引。然而,这只是冰山一角,最常用的是综合指数。让我们从引入复合指数开始。

概念:索引包含多个字段,索引根据多个列进行排序。

分类方法

假设column_ 01是数字09,column _

1按column_ 01对列进行排序,即按0到9的顺序

2如果列_ 01相同,则按列_

3当列_ 02相同时,根据列_。

例如,可以通过以下方式对分组进行类比:

复合索引的B+树结构

注:许多文章将单值索引的B+树结构直接应用于复合索引,但事实并非如此。请记住,B+树将所有数据存储在叶节点中,而非叶节点仅负责划分检索叶节点的间隔 复合索引不是这种情况,B+树的每个节点都包含所有索引键,并按索引键排序。

搜索顺序:

当我们的SQL语句为.age=15时,您可能会发现多行记录。在这种情况下,您将根据电子邮件的排列顺序进行搜索。当电子邮件相同时,例如,“三封”和“三封小”电子邮件相同,您将根据uname进行搜索。

这种查找确实比逐行匹配原始表更快。

为什么要在每个节点中存储所有索引键

问一个问题,你可能会得到这个想法。

Q: 如果创建索引,索引的B+树结构是什么

对于为什么每个节点都存储所有索引键,您可能已经有了答案。

如果像单值索引那样,只在每个非叶节点上存储第一个键,那么mysql将不得不选择使用其混乱的批排序算法进行排序。因为它只在B+树中的非叶节点中看到“国籍”字段。

功能:用于查看SQL语句的执行参数,方便技术人员分析慢速查询

原文读起来很有趣。如果你不懂英语,请使用翻译工具。

左倾原理

最左原则适用于复合指数。简单地说,在查询时,column_

例如:

首先创建索引

然后查询它

请注意,在group by即column_02之后跳过column_。失败后,mysql将直接返回原始表,并使用自己的“非常慢”排序方案进行组排序,这与没有创建索引的情况相同。如果您了解B+树中复合索引的逻辑结构,您可以了解为什么存在“最左规则”。

实际操作01

C: 插入一些数据

D: 在步骤C中,首先查询并比较数据的顺序

F: 根据key_len,假设使用了三个索引键,ageemail和uname。年龄需要4个字节,电子邮件需要62个字节,取消电子邮件需要92个字节。key_len用于确定每个查询使用了多少索引键。

原因:

Int占4字节;

电子邮件占用+1字节+1字节=62字节;

Uname占用+1字节+1字节=92字节;

所以4加62加92正好等于158。

G: 得出结论

当查询时,mysql会自动在索引中找到我们想要的数据,然后将其显示给查询者。

实际操作02

A: 当我们执行时。-20200527162534043 在学习覆盖索引之前,我们需要知道什么是返回表操作(什么是覆盖索引和回表) 热门话题

好的,看看额外的列,使用索引,按照我们的意图使用索引。

B: 当我们执行时。20200527162809169 在学习覆盖索引之前,我们需要知道什么是返回表操作(什么是覆盖索引和回表) 热门话题

好的,看看额外的列,使用索引,我们仍然按照我们的需要使用索引,没有问题。

为什么

D: 得出结论

因此,如果在索引中,您对电子邮件进行排序时没有年龄,但年龄=15,则必须对该本地节点中的电子邮件进行排序。但如果是一封全球性的电子邮件,即使是本地订购的,也会很混乱。

这就是为什么会有“最左原则”的原因!

主键索引

我们反复提到主键索引,但我们知道它将自动创建,但我们没有提到自动创建它需要满足的条件。

回到桌子上

在学习覆盖索引之前,我们需要知道什么是返回表操作。

让我们继续上面描述的user_ table。但是这次你要创建的索引是-20200528111939087. 在学习覆盖索引之前,我们需要知道什么是返回表操作(什么是覆盖索引和回表) 热门话题

当我们执行时,我们知道age和uname是索引键,这两个字段自然会首先排序并保存到索引文件中。电子邮件是非索引键,在索引文件中找不到有关电子邮件的信息。

使用Where与我们当前的主题无关。我们关心的是没有使用索引键,这表明mysql已经使用了我们创建的所有内容,但为什么呢

由于返回表操作采用两个索引,因此其效率必须低于仅采用一个索引。

索引覆盖

在上述返回表操作中。

现在我们需要执行。

经过分析,我们发现mysql使用了Using索引。

我们将这种直接从索引中提取数据而不返回表的现象称为索引覆盖。

将继续更新,敬请期待~


相关推荐

发表评论