【问题标题】:How to get statistics on time MySQL spent updating indexes during a new row insertion如何获取 MySQL 在新行插入期间更新索引所花费时间的统计信息
【发布时间】:2019-09-17 16:26:11
【问题描述】:

我试图弄清楚多个索引实际上是如何影响 MySQL InnoDB 表的插入性能的。

是否可以使用 performance_schema 获取有关索引更新时间的信息?

似乎没有可以反映此类信息的阶段工具。

【问题讨论】:

  • 使用和不使用索引测试它。然后比较时间。
  • @PaulSpiegel 在生产服务器上删除索引并不容易:)
  • 无论是否删除索引,我都不会在生产服务器上运行 INSERT 测试。这就是存在测试服务器的原因之一。

标签: mysql performance database-performance


【解决方案1】:

即使 performance_schema 中有东西,它也是不完整的。

非唯一二级索引是这样处理的:

  1. INSERT 开始。
  2. 任何UNIQUE 索引(包括PRIMARY KEY)都会立即检查“dup key”。
  3. 其他索引更改被放入“更改缓冲区”。
  4. INSERT 返回客户端。

更改缓冲区是保存此类索引修改的 buffer_pool(默认值:25%)的一部分。最终,它们将被批量更新索引的 BTree 的实际块。

在好的情况下,许多索引更新将组合成很少的读-修改-写步骤来更新一个块。在较差的情况下,每次索引更新都需要单独的读取和写入。

更改缓冲区的 I/O 在“后台”完成,最终写入数据块的任何更改也是如此。这些无法以任何方式进行实际监控——尤其是当不同的客户端具有不同的查询对相同的索引或数据块进行更新时。

哦,与此同时,任何索引查找都需要在磁盘上(或缓存在 buffer_pool 中)块和更改缓冲区中查找。这使得索引查找更快或更慢,具体取决于与手头操作无关的各种事情。

【讨论】:

  • 从服务器(在主从复制中)是否发生相同的过程?当特定会话在 Master 上执行一些 INSERT(或任何其他 DML)时;是否会发生将更改批处理到更改缓冲区的相同过程?我问的原因是人们建议从主之间进行读写负载分离;但是如果 Slave server 也经历了同样的流程,那它到底是如何脱颖而出的呢?
  • @MadhurBhaiya - 所有 DML 操作都发生在所有服务器(主服务器和从服务器)上。而且大部分努力也被复制了。基于行的复制避免了复制一些开销。但仍然需要更新索引。
  • 有道理,但是当我们对它们中的任何一个执行相同的 Select 查询时,为什么只读从属服务器的性能优于主服务器。我正在经历这个;我之前的理解是,Master 不断地进行 DML 操作,从而导致读取速度变慢(由于锁定等);复制通过一些不同的方式(比如某种二进制文件同步)来处理数据一致性。
  • @MadhurBhaiya - 通常情况下,Master 上还有很多事情要做。例如:SELECT FOR UPDATE 在更新之前; UPDATE 缺少好的索引;等等。这会导致锁在 Master 上的持续时间更长。
猜你喜欢
  • 2021-12-25
  • 2010-10-24
  • 2012-03-24
  • 1970-01-01
  • 2015-07-15
  • 1970-01-01
  • 2021-06-26
  • 1970-01-01
  • 2014-06-27
相关资源
最近更新 更多