将索引提升为主键

时间:2017-01-13 15:22:19

标签: mysql sql mariadb

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

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

......但这需要很长时间,似乎很浪费。 (该表的大小为几十GB,并且在一台机器上运行,其可用磁盘空间少于表的总大小。)我意识到索引和主键不是一回事(至少,主键包括必须在创建过程中检查的唯一性约束),但有没有办法使用索引来“引导”主键?

1 个答案:

答案 0 :(得分:0)

假设该表为ENGINE=InnoDB ?? ...

如果磁盘上没有足够的可用空间用于表的另一个副本,则在没有第二台服务器的帮助下无法执行该任务。你可以丢几张桌子吗?或以其他方式腾出空间?

PRIMARY KEYUNIQUE并且是索引。如果barbaz的组合不是唯一的,则不应将其转换为PK。

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

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

是的,您桌上目前有PRIMARY KEY。它是一个6字节的隐藏“列”。你的ALTER会扔掉它,从而使桌子变得更小(另一个小的好处)。

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

好的,可能希望。如果您使用OFF运行,ibdata1中有足够的空间,则任务可能会完成。 (但这意味着,如上所述,你已经臃肿了ibdata1。)