mysql - 将索引提升为主键

标签 mysql sql mariadb

我在 MariaDB 数据库中有一个表,没有为其定义主键。但是,它有一个索引。我想添加一个与该索引具有相同定义的主键。天真的方法可能是:

alter table `foo` add primary key (`bar`, `baz`),
                  drop index `qux`;

...但这将花费很长时间并且看起来很浪费。 (该表的大小为数十 GB,并且在可用磁盘空间小于表总大小的计算机上运行。)我意识到索引和主键不是同一件事(至少,主键包含唯一性约束,必须在创建过程中检查),但是有没有办法使用索引来“引导”主键?

最佳答案

假设表是ENGINE=InnoDB??...

如果磁盘上没有足够的可用空间用于表的另一个副本,则在没有第二个服务器的帮助下无法执行该任务。你能放下一些 table 吗?或者以其他方式释放空间?

PRIMARY KEYUNIQUE 并且是一个索引。如果barbaz的组合不唯一,则不应将其变成PK。

使用 PK 查找单行比使用二级索引更快。这是因为它首先在二级索引的 BTree 中查找该行。它在那里找到PRIMARY KEY,然后用它来查找数据 BTree 中的行。

如果表大于innodb_buffer_pool_size,您的更改也将(在许多情况下)消除磁盘命中。 (磁盘命中是数据库操作中最慢的部分。)

是的,您的 table 上当前有一个主键。它是一个 6 字节的隐藏“列”。您的 ALTER 会将其丢弃,从而使表格变小一点(另一个小好处)。

您是否有innodb_file_per_table=ON(或=1)?如果该表位于其自己的 .ibd 文件中,则您将在操作后恢复磁盘空间(假设它完全可以运行)。如果OFF,它将增加ibdata1 文件的大小,但无法将其缩小。 在创建最终会变得“大”的表时将其ON

好吧,也许还有希望。如果您在OFF 下运行,并且ibdata1 中有足够的空间,则任务可能会完成。 (但这意味着,正如上面提到的,您已经使 ibdata1 膨胀了。)

关于mysql - 将索引提升为主键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41637898/

相关文章:

MySql 最大内存过高,仍要求增加

php - 通过php将多个文件的数据插入mysql数据库

mysql - 如何编辑 docker mysql 镜像并增加连接限制

MySQL 对字符串执行数学运算?

mysql - 在 Mysql/Mariadb 中删除 --temporary-- 索引

sql - 如何在go lang中从数据库中获取数据

mysql - 我可以在 InnoDB 事务期间检索挂起的查询吗?

MySQL 游标无法选择获取变量

MySQL : Indexes for View based on an aggregated query

sql - 使用内连接更新记录