【问题标题】:Disk IO in MySQL clustered indexMySQL 聚集索引中的磁盘 IO
【发布时间】:2019-04-24 18:43:04
【问题描述】:

了解到mysql中一个聚集索引的叶子节点是存储行数据的。

如果从聚集索引中检索数据,是否会发生物理磁盘IO?

【问题讨论】:

  • 如果索引节点不在内存中,当然是在内存中。还能怎么用?
  • “如果从集群索引中检索数据,不会发生物理磁盘io吗?”还要添加到@Barmar的评论SELECT <columns> FROM table WHERE <indexed_column> = '<value>'可以/仍然需要磁盘或内存 I/O 以获取不在索引文件中的列数据..
  • 索引不会阻止磁盘 I/O,它们只是减少它。中间节点比叶节点小,因此它们可以在内存中放置更长的时间。
  • “索引不会阻止磁盘 I/O,它们只会减少它” 是的,不是的从表中获取完整的数据集.. 我宁愿看到 1 个随机磁盘请求(1 * 4 毫秒)与 1 个随机磁盘请求(使用索引时的每个记录)(n * 4 毫秒).. 但是这个问题在很大程度上移动了繁重的数据库理论和优化器..
  • 是的,我在简化。他们在很多情况下都会减少它,但有时查询规划器会确定索引没有好处。

标签: mysql indexing innodb


【解决方案1】:

如果 InnoDB Buffer Pool 中的 RAM 中尚未有页面,InnoDB 必须从磁盘中获取页面。

一旦被提取,一个页面会保留在缓冲池中,除非它被其他页面逐出,或者 MySQL 服务器进程重新启动。

当页面在缓冲池中时,后续读取该页面的请求会从 RAM 中读取它,而不是产生磁盘 IO。

【讨论】:

    【解决方案2】:

    简答

    问:如果从聚簇索引中检索数据,会不会发生物理磁盘IO?

    答:视情况而定。很多事情。

    长答案

    I/O 是查询中最慢的部分。 (如果所有内容都被缓存,那么其他考虑因素将成为“最糟糕的”。)在猜测查询需要执行多少 I/O 时,我喜欢做出以下简化假设:

    • 扇出为100。即BTree(数据或索引)中的每个非叶子节点在其下大约有100个节点。在 OP 的图中,扇出只有 2 - 适合页面的必要简化; 100 更真实。

    • 在计算 I/O 时,只需要计算数据的叶节点。在很多种情况下,这是一种过度简化,但在运行平稳的生产系统中,这是相当不错的。

    这两个简化避免了已经指出的血腥细节。想一想——非叶数据节点可能占 BTree 节点的 1%,因此生产系统可能会到达所有这些节点的缓存位置。

    “点查询”可能需要 I/O。 “范围查询”可能需要每读取 100 行读取一个块。请注意,您永远不会使用 UUID 进行“范围查询”。

    在 InnoDB 中,INDEX(包括 UNIQUE) is very much like a clustered index, with the exception of what is in the leaf nodes. The "rows" of anINDEXcontain the column(s) of thePRIMARY KEY`。这些列用于向下钻取数据的 BTree 以获取其余列。

    “使用索引”表示“覆盖索引”,这意味着所有SELECT 所需的列都在INDEX's BTree 中找到。在这种情况下,可以避免反弹到数据 BTree。

    所有块(叶子/非叶子,数据/索引)都被(几乎)相同地对待。来自 buffer_pool 的来来去去(大致)是最近最少使用的算法。这使得计数 I/O 基本上是不可能的。所以,我估计。

    【讨论】:

      猜你喜欢
      • 2011-09-15
      • 2018-05-22
      • 2019-05-20
      • 1970-01-01
      • 2013-11-21
      • 2017-05-08
      • 1970-01-01
      • 2010-09-08
      • 2012-04-28
      相关资源
      最近更新 更多