【问题标题】:InnoDB B+ tree index - duplicate valuesInnoDB B+ 树索引 - 重复值
【发布时间】:2016-11-06 21:58:51
【问题描述】:

在 InnoDB 的 B+ 树实现中如何处理重复键的索引。

例如,如果有一个有 100 万行的表,其中有一列的基数为 10。如果我们在该列上创建索引,生成的 B+ 树会是什么样子?

它是否只有 10 个键,每个键的值是属于该键的主键列表(如果是,采用什么结构?链表?)还是有 1M 键(如果是,则 B+树必须以不同的方式处理)?

【问题讨论】:

    标签: mysql innodb b-tree


    【解决方案1】:

    在某种意义上,InnoDB BTree 没有重复项。这是因为PRIMARY KEY 的列被附加到为辅助键指定的列中。这会导致一个完全有序的列表。

    当您通过辅助键(或键的初始部分)查找时,查询将向下钻取 BTree 以找到与您提供的索引匹配的第一行,然后向前扫描以获取任何其他行。要获取其余列,它需要 PRIMARY KEY 列进行第二次 BTree 查找。

    优化器很少使用“低基数”的索引。例如,不应为 yes/no 或 true/false 或 male/female 列编制索引。优化器会发现简单地扫描表比在索引和(通过 PK 列)主 BTree 之间来回跳转更快。

    何时使用指数与下注的截止值约为 20%,具体取决于月相。

    【讨论】:

    • 谢谢瑞克。这似乎是有道理的。你有任何参考 - 在手册或其他地方?
    • 唉,不。文档中有许多网页,但它们往往更精确,实用性较差。这是我收集的关于索引如何工作的知识的一部分。我尝试将其改写为“可用”的方式。我已经反复看到了 20%(10% 到 30%)的演示。 5.7 重新设计了用于决定查询计划的“成本模型”,但仍然归结为我所说的。
    【解决方案2】:

    错误索引

    您提出的案例对于 B+ 树来说是一个糟糕的案例。基数 10 表示 only 10 of the 1 million values are unique。实际上,它不仅对 B+ 树不利,而且通常是一个糟糕的索引。根据该指数,您平均会留下大约 1 个子集。 100,000 个值,您必须仔细查看或使用其他值进一步过滤。

    B+ 树属性

    关于生成树的结构,这里有一些注意事项:

    1. 一个节点不能包含任意多的数据。
    • 如果叶节点已满,插入可能需要拆分
    • 有时叶节点的分裂需要下一个更高节点的分裂
    • 在最坏的情况下,拆分可能会一直级联到根节点

    https://www.percona.com/files/presentations/percona-live/london-2011/PLUK2011-b-

    1. 叶子以双链表的形式链接。
    • 叶子节点作为双向链表链接在一起
    • […]
    • 可以扫描整个树而根本不访问更高的节点

    https://www.percona.com/files/presentations/percona-live/london-2011/PLUK2011-b-

    期待

    如果您使用或多或少都属于同一个等价类的键插入大量数据,我会期望一棵树,这不会有太大帮助。这 10 个键可能仅存在于根节点中,并且树中更深的所有数据都将未排序(因为没有任何东西可以对其进行排序)。

    由于叶子是双链表,因此您基本上只剩下我在开头所写的内容:您必须遍历值的一大子集。关于给定的索引,这是可以预料的,并且 B+ 树在这种情况下可能会做得很好(一个列表可以用于遍历所有数据)。

    实际上,这是一种更深层次的抽象:叶子是双链接的,但每个叶子中有多个值(数据或链接到 PK)。尽管如此,这些也都在一个列表中,所以如果你只是遍历所有内容并没有太大区别。

    检查 InnoDB 空间

    请注意,您还可以调查 MySQL 真正构建的内容。有一些工具可以检查构建的索引数据结构,例如

    【讨论】:

    • 我知道这是一个糟糕的索引。这只是为了我对innodb内部的理解。抱歉,您的回答并不清楚这些数据将如何存储在树中。我会尝试链接中的工具。谢谢。
    • 也许您应该只阅读我提供的两个链接以及与此相关的 MySQL 手册。手册中有(或至少有)一章解决了 MySQL 内部问题,如果您也对此感兴趣(也许查看旧版本的手册)。
    【解决方案3】:

    InnoDB 将表存储在内部称为 PRIMARY 的 B+ 树索引中。索引的键是你的主键字段。

    如果您定义二级索引,则会有额外的 B+ 树索引(在 .ibd 或 ibdata1 中),其中键是二级索引字段,值是主键。

    B+ 树本身并不要求 key 是唯一的。 PRIMARY 和所有 UNIQUE 索引的唯一性在服务器级别强制执行。

    这里有一些幻灯片,介绍了 InnoDB 如何组织索引并使用它们来访问数据。 http://www.slideshare.net/akuzminsky/efficient-indexes-in-mysql#downloads-panel

    【讨论】:

      猜你喜欢
      • 2016-03-16
      • 2015-04-25
      • 2019-11-18
      • 1970-01-01
      • 1970-01-01
      • 2021-09-23
      • 1970-01-01
      • 1970-01-01
      • 2018-10-19
      相关资源
      最近更新 更多