mysql - 在 MySQL 表上创建外键需要很长时间才能复制到 tmp 表

标签 mysql performance foreign-keys alter-table

我正在尝试在包含 30M+ 行的 5.7 InnoDB 表上设置外键约束。

它现在已经在四核 64GB 服务器上运行了 45 分钟。 processlist 输出发出的 alter table 命令的状态复制到临时表

InnoDB_buffer_pool_size 设置为 32G 并且有空间。

为什么系统要创建 tmp 表,这可以以某种方式提高性能吗?

最佳答案

很可能花时间为该外键构建索引。如果您已经有一个索引,其中外键列是索引的最左边的列,那么它将使用该索引而不是构建新索引。

在如此大的表上构建索引,45 分钟听起来并不奇怪。您还没有说明外键列的数据类型是什么,因此它可能是一个很大的 varchar 或其他类型,并且构建该索引需要花费很多 GB 的空间。

也许您的服务器磁盘速度太慢。如果您使用非 SSD 存储或远程存储(例如 Amazon EBS),按照现代标准来看,它的速度很慢。

CPU 核心不会产生任何影响,因为无论如何工作都是在一个线程中完成的。更快的 CPU 速度会有所帮助,但更多的内核则无济于事。

在我的公司,我们使用pt-online-schema-change应用所有架构更改或索引构建。这允许客户端同时读取和写入表,因此花费 45 分钟或 90 分钟甚至更长的时间并不重要。最终它完成了,并将新表替换为旧表。

关于mysql - 在 MySQL 表上创建外键需要很长时间才能复制到 tmp 表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65604537/

相关文章:

Mysql创建group_concat联合

Php、MySql、具有两个计数的单个查询

performance - 为什么 VS2019 在尝试调试 c# 应用程序时突然变得非常缓慢和滞后?

python - 使用 .executemany() 加速 MySQL INSERT 操作

MySQL 多对多表主键

mysql - 无法在mysql中建立外键约束

mysql - 向 MySQL 表添加大列(VARCHAR)会对性能产生重大影响吗?

mysql - 在不使用参数计划的情况下在 mysql 数据库中输入新数据时通知 Logstash

python - Pandas Pytables 警告和性能缓慢

连接语句的 MySql 查询限制和排序