nic*_*ico 24 mysql sql phpmyadmin
我有这样一个有三列的大表:
+-----+-----+----------+
| id1 | id2 | associd |
+-----+-----+----------+
| 1 | 38 | 73157604 |
| 1 | 112 | 73157605 |
| 1 | 113 | 73157606 |
| 1 | 198 | 31936810 |
| 1 | 391 | 73157607 |
+-----+-----+----------+
Run Code Online (Sandbox Code Playgroud)
这持续38米行.问题是我想删除'associd'列,但运行ALTER TABLE table_name DROP COLUMN associd;只需要太长时间.我想要做这样的事情:ALTER TABLE table_name SET UNUSED associd;和ALTER TABLE table_name DROP UNUSED COLUMNS CHECKPOINT 250;那么这显然加速了过程,但它是不可能在MySQL?
是否有替代方法可以删除此列 - 可能只创建一个只包含两列的新表或者使用检查点进行删除?谢谢!
Gor*_*off 33
你做的任何事情都需要读取和写入38米的行,所以没有什么是真正的快速.可能最快的方法可能是将数据放入新表:
create table newTable as
select id1, id2
from oldTable;
Run Code Online (Sandbox Code Playgroud)
或者,如果您想确保保留类型和索引:
create table newTable like oldTable;
alter table newTable drop column assocId;
insert into newTable(id1, id2)
select id1, id2
from oldTable;
Run Code Online (Sandbox Code Playgroud)
但是,在加载一堆数据然后重新创建索引之前,通常会更快地删除表上的所有索引.
免责声明:这个答案是面向 MySQL 的,可能不适用于其他数据库。
我认为在接受的答案中缺少一些东西,我试图在这里公开我用来在生产环境中执行此类操作的通用序列,不仅用于添加/删除列,还用于添加索引。
我们称之为印第安纳琼斯运动。
使用旧表作为模板的新表:
create table my_table_new like my_table;
Run Code Online (Sandbox Code Playgroud)
在新表中:
alter table my_table_new drop column column_to_delete;
Run Code Online (Sandbox Code Playgroud)
不会在create table like命令中自动生成。
您可以检查实际的外键:
mysql> show create table my_table;
Run Code Online (Sandbox Code Playgroud)
然后将它们应用到新表:
alter table my_table_new
add constraint my_table_fk_1 foreign key (field_1) references other_table_1 (id),
add constraint my_table_fk_2 foreign key (field_2) references other_table_2 (id)
Run Code Online (Sandbox Code Playgroud)
复制所有字段,但要删除的字段除外。
where如有必要,我使用一句话可以多次运行此命令。
因为我认为这是一个生产环境,my_table它将不断有新记录,所以我们必须保持同步,直到我们能够更改名称。
我还添加了一个,limit因为如果表太大且索引太重,则一次性克隆可能会关闭数据库的性能。另外,如果在此过程中您想取消操作,则必须回滚所有已完成的插入,这意味着您的数据库不会立即恢复(https://dba.stackexchange.com/questions/5654/内部原因杀死进程占用时间在 mysql 中)
insert my_table_new select field_1, field_2, field_3 from my_table
where id > ifnull((select max(id) from my_table_new), 0)
limit 100000;
Run Code Online (Sandbox Code Playgroud)
由于我多次这样做,我创建了一个程序:https : //gist.github.com/fguillen/5abe87f922912709cd8b8a8a44553fe7
确保在复制表中的最后一条记录后立即运行此命令。理想情况下一次运行所有命令。
rename table my_table to my_table_3;
rename table my_table_new to my_table;
Run Code Online (Sandbox Code Playgroud)
在执行此操作之前,请确保您有备份;)
drop table my_table_3
Run Code Online (Sandbox Code Playgroud)
免责声明:我不确定指向旧表的外键会发生什么。