【问题标题】:Innodb, clustered indexes, and slow_query_log - hurt by the primary key?Innodb、聚集索引和 slow_query_log - 被主键伤害?
【发布时间】:2015-05-13 22:04:32
【问题描述】:

在过去的几个月里,我们将一些表从 MYiSAM 迁移到了 InnoDB。理论上,我们这样做是为了行锁定优势,因为我们正在通过多个网络抓取实例更新单个行。我现在在我的 slow_query_log (10s) 中建立了数以万计的 slow_queries。和很多全表扫描。我对一行进行非常简单的更新(更新 4 或 5 列)需要 28 秒。 (我们的 I/O 和效率非常好,失败/中止的尝试非常低

我们更新最多的两个表都以 ID (int 11) 作为主键。在 InnoDB 中,主键是一个聚集键,因此按 ID 顺序写入索引的磁盘。但是我们最重要的两个记录识别列是BillsofLadingContainer(都是varchar22)。我们的大多数 DML 查询都基于这两列查找记录。我们在BillsofLadingcontainer. 上也有索引 按照我的理解,InnoDB在创建这两个二级索引的时候也是使用主键的。

因此,我可以有一条记录为ID=1 和BillsofLading='z',以及另一条记录ID=9 和BillsofLading='a'。使用 InnoDB 索引,当基于 BillsofLading='a' 的 SELECT 更新记录时,由于索引基于 ID,我是否仍需要进行全面扫描才能找到 'a'?

提前感谢您在此处提供逻辑帮助!

【问题讨论】:

  • 首先要做的是运行EXPLAIN来找出查询执行计划是什么以及资源被消耗在哪里。使用像 Mysql Workbench 或 Toad 这样的 GI 来运行解释,因为它们可以更好地呈现结果。
  • @DavidSoussan 我没有从 EXPLAIN 扩展中得到任何明显的指标。想知道它是否更多地是应用程序处理的指标,而不是实际的 DML 语句。
  • SHOW CREATE TABLE -- 可能有明显的事情。

标签: mysql innodb clustered-index full-table-scan


【解决方案1】:

您是否严重减小了 key_buffer_size 并将 innodb_buffer_pool_size 设置为可用 RAM 的 70% 左右?

MyISAM 和 InnoDB 之间存在许多细微差别。这个答案中有太多要列出的内容,您所说的任何内容都没有让人想起任何特定问题。我建议您查看Converting MyISAM to InnoDB 以了解可能导致问题的原因。

【讨论】:

  • 好问题。我正在调查这些。我知道 i/o 值看起来不错。
【解决方案2】:

不,假设 MySQL 选择使用您的 BillsofLading 索引,您的示例不需要完整扫描。你说

按照我的理解,InnoDB在创建这两个二级索引的时候也是使用主键的。

这是正确的,但并不意味着你认为它的意思。

InnoDB 的主键 (PK) 就像人类的行号。这是 InnoDB 唯一标识行的唯一方法。因此,二级索引所做的是将目标列的每个值映射到与该值匹配的所有 PK(即行号)。因此,MySQL 可以快速跳转到您关心的 BillsofLading,然后仅扫描那些行 (PK) 以找到您想要的行。

【讨论】:

  • 啊,所以它根据账单索引找到BillsofLading,然后使用主键(行号)转到其余列的那一行?谢谢你的解释。
  • 当然。为了解决您的整体查询效率问题,我建议从慢查询日志中最严重的违规者(或者可能也是相对简单的查询的最严重违规者)开始,并特别调查该查询出现问题的原因。这可能会解释为什么所有其他查询也有问题。
猜你喜欢
  • 1970-01-01
  • 2013-04-30
  • 2021-09-07
  • 1970-01-01
  • 1970-01-01
  • 2011-05-15
  • 2012-06-03
  • 1970-01-01
  • 2018-12-01
相关资源
最近更新 更多