为将来的任何发现者发布这个。做了一些研究后,我发现这是一个理想的解决方案,我可以放在一起。
步骤1:创建一个新的临时表,它的结构与我们试图缩减的临时表完全相同。
步骤2:标识引用有问题的类(x)的表/列。
SELECT *
FROM information_schema.COLUMNS
WHERE table_schema = 'my_db_name'
AND column_name LIKE '%reference_column%'
步骤3:对于那些具有非空引用的表/列中的每一行,获取它们引用的x行,并将其复制到新表(如果新表中不存在该行)。我一个表一个表地做,并使用一次1000条记录的分块方法来节省系统内存。我在应用程序层中编写了这个逻辑,以便更好地控制它。我用过
INSERT IGNORE
避免创建主键冲突,因为某些引用指向同一个x对象。
步骤4:删除旧表,将新表重命名为与旧表相同的名称。
SET FOREIGN_KEY_CHECKS=0;
DROP TABLE old_table;
RENAME TABLE new_table TO old_table;
SET FOREIGN_KEY_CHECKS=1;
所有这些都告诉我们,在我的环境中运行大约需要一个小时,其中表x有大约700万行,而我有大约10个其他表引用它。