我在 MariaDB 数据库中有一个表,没有为其定义主键。但是,它有一个索引。我想添加一个与该索引具有相同定义的主键。天真的方法可能是:
alter table `foo` add primary key (`bar`, `baz`),
drop index `qux`;
...但这将花费很长时间并且看起来很浪费。 (该表的大小为数十 GB,并且在可用磁盘空间小于表总大小的计算机上运行。)我意识到索引和主键不是同一件事(至少,主键包含唯一性约束,必须在创建过程中检查),但是有没有办法使用索引来“引导”主键?
最佳答案
假设表是ENGINE=InnoDB
??...
如果磁盘上没有足够的可用空间用于表的另一个副本,则在没有第二个服务器的帮助下无法执行该任务。你能放下一些 table 吗?或者以其他方式释放空间?
PRIMARY KEY
是UNIQUE
并且是一个索引。如果bar
和baz
的组合不唯一,则不应将其变成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/