【发布时间】:2013-12-23 02:59:52
【问题描述】:
我们有一个外部 PHP 脚本,它从数据库中的各个表中提取数据,以创建对同一数据库中其他几个表的更新。出于这个问题的目的,我不会讨论该脚本提取的内容或它如何生成数据,但我感兴趣的是它如何更新数据库中的表。
目前该脚本不做任何类型的差异,而是创建一个 SQL 脚本来创建一个临时表并将它生成的数据插入到该临时表中。然后它TRUNCATEs 生产表和INSERT/SELECT 来自临时表的所有内容。
我应该注意,此脚本每次运行时生成的数据都可能不同,具体取决于在其他表中删除、添加或更改的内容。
这是它正在做的一个经过净化的版本:
CREATE TEMPORARY TABLE tbl0_temp (col1, col2, col3, PRIMARY KEY (col1,col), UNIQUE KEY tuple (user_id,nas_id));
INSERT INTO tbl0_temp VALUES (valA1, valB1, valC1),(valA2, valB2, valC2),(valA3, valB3, valC3),...you get the idea.
TRUNCATE TABLE tbl0_prod;
INSERT INTO tbl0_prod SELECT * FROM tabl1_temp;
这种方法在几年前生产表 (tbl0_prod) 中只有几千行的情况下运行良好,但现在我们有接近几百万行。鉴于此,该方法并不是慢得离谱,但在某些副本上,INSERT/SELECT 可能需要长达 30 秒。那是 30 秒,远程计算机上的应用程序没有获得所需的数据,人们确实注意到了。
我希望有一种更好、更快、影响更小的方法来更新该表。我想知道创建/更新“真实”表并简单地进行一些重命名是否可行。这是我的想法的一个例子:
CREATE TABLE IF NOT EXISTS tbl0_temp LIKE tbl0;
TRUNCATE TABLE tbl0_temp;
INSERT INTO tbl0_temp VALUES (valA1, valB1, valC1),(valA2, valB2, valC2),(valA3, valB3, valC3),...
RENAME TABLE tbl0 TO tbl0_old, tbl0_temp to tbl0;
RENAME TABLE tbl0_old TO tbl0_temp;
保留tbl0_tmp 表背后的想法是,如果出现问题,很容易将内容重命名回来,但或者我可以删除tblo_old,甚至不必担心开头的截断。
在我看来,这似乎是一个好主意,但这是我在后端可能产生的影响方面遇到的知识鸿沟。有没有人碰巧有任何见解(根据我提供的有限信息)这是否可行,或者是一个坏主意?
主副本和大多数副本上的版本是 5.0.46。所有有问题的表都是 MyISAM。
【问题讨论】:
标签: mysql insert rename temp-tables truncate