我需要更新一个表,其中包含可以添加/更新/删除数据的表中预先计算的值。
我可以用
insert into precalculated(...)
select ... from ...
on duplicate key update ...
添加/更新预先计算的表但是有一个优化方法来删除过时的行吗?
答案 0 :(得分:1)
我认为您应该创建一个存储过程,当且仅当记录满足条件时才会删除相关表的数据。
您的问题中没有足够的信息来设计程序,但我可以给您一些例子:
delimiter $$
create procedure delete_orphans()
begin
declare id_orphan int;
declare done int default false;
declare cur_orphans cursor for
select distinct d.id
from data as d
left join precalculated as p on d.id = p.id
where p.id is null;
declare continue handler for not found set done = true;
open cur_orphans;
loop_delete_orphans: loop
fetch cur_orphans into id_orphan;
if done then
leave cur_orphans;
end if;
delete from data where id = id_orphan;
end loop;
close cur_orphans;
end$$
delimiter ;
此过程将删除data
表中precalculated
表中至少没有一个相关行的每一行。
当然,这种方法可能不合适,因为它会逐个删除行,但正如我所说,这只是一个例子。您可以根据自己的需要进行自定义。
如果需要,您可以从触发器调用此过程(使用call delete_orphans()
)。
希望这有帮助。
答案 1 :(得分:1)
由于您总是添加或更新这些其他表中存在的行,并且您想要删除任何不存在的行,为什么不这样做:
DELETE FROM precalculated
insert into precalculated(...)
select ... from ...
on duplicate key update ...
始终开始清洁意味着您以后不必担心孤儿。
答案 2 :(得分:1)
您可以在维护precalculated
的主表上添加插入,删除和更新的触发器。
插入或更新时,可以使用相同的代码计算值并发出replace into precalculated (...) values (...)
删除它时可能相同,另外还要删除precalculated
中孤儿的行。在这里要聪明并使用原始删除中的值来查询precalculated
的孤儿,而不是进行表扫描。
答案 3 :(得分:0)
我可能已经使用重命名找到了我的解决方案。
所以基本上,我会做一个简单的插入选择到临时表,然后
rename precalculated to precalculated_temprename, precalculated_temp to precalculated, precalculated_temprename to precalculated_temp;
truncate precalculated_temp;
需要一些测试,但似乎重命名操作是快速和原子的。