SQL:删除+插入 vs 更新+插入

6
一个类似的问题已经被问过了,但由于情况因人而异,我要单独为我的特定情况提问。
我有一个网站页面显示一些来自数据库的数据,并且为了从数据库生成数据,我必须进行一些相当复杂的多重连接查询。
数据每天(晚上)更新一次。
我想预先生成所需视图的数据以加快页面访问速度。
为此,我正在创建一个包含我需要的确切数据的表。
问题:对于我的情况,完全清除表后插入是合理的吗?还是应该进行更新和插入?
从SQL的角度来看,DELETE + INSERT似乎更容易(INSERT部分是一个单一的SQL表达式)。
编辑:RDBMS:MS SQL Server 2008 Ent

1
你使用的是哪个数据库?(在我使用的几个关系型数据库管理系统中,“DELETE”和“INSERT”不能组成“单个SQL表达式”。) - pilcrow
我的错,我是说INSERT是一个语句,而不是DELETE+INSERT是一个语句。 - THX-1138
7个回答

13

如果需要清空表格,TRUNCATE 指令比 delete 更快。

您没有说明您的 RDBMS 供应商,但其中一些供应商也有 MERGE/UPSERT 命令,这使您可以在数据存在时更新表格,在不存在时插入数据。


RDBMS: MS SQL Server 2008 Ent - THX-1138
2
2007不存在,您是指2005还是2008?如果是2008,请查看MERGE http://msdn.microsoft.com/en-us/library/bb510625.aspx。 - SQLMenace
是的,2008年(IIS为7)-合并似乎是完美的解决方案。 - THX-1138

1

这在一定程度上取决于数据的访问方式。如果有一个时间段没有(或者非常少量)用户访问它,那么在 DELETE 和 INSERT 完成之间短暂的数据消失对数据影响不大。


1
你是否考虑过使用物化视图(MSSQL称之为索引视图)而不是手动实现?这种方法还可以带来其他的性能优势,因为对于引用视图中表的查询操作,索引视图会给查询优化器提供更多的选择,以便在构建执行计划时作出最优决策。

在 SQL Server 中,物化视图不允许外部和自连接,而这是任何值得实现的查询所包含的内容。如果没有这个限制,物化视图将是完美的解决方案。 - THX-1138

0

这取决于表的大小和数据库上的恢复模式。如果您要删除数十万条记录并重新安装它们,而不是更新几百个小批次并插入数十行,则会使事务日志不必要地增加。但是,您可以使用TRUNCATE来解决此问题,因为它不会影响事务日志。

您是否有MERGE / UPSERT选项?如果您使用MS-SQL,如果没有,可以使用CROSS APPLY进行类似的操作。


0

处理这种类型问题的一种方法是插入新表,然后进行表重命名,这将确保所有新数据同时存在。


假设需要多次插入,只要所有的插入都在一个事务中完成,就不需要这个操作。 - Donnie

0

如果昨天存在的某些数据现在已经不存在了怎么办?删除可能更安全,否则您可能会误删一些记录。

最终,无论您选择哪种方式,都不会真正影响结果。除非是@kevinw提到的情况。


0

虽然我完全同意SQLMenace's answer,但我想指出MERGE不会删除不需要的记录!如果您确定新数据将是现有数据的超集,则MERGE很棒,否则您将需要确保稍后删除任何多余的记录,或使用TRUNCATE + INSERT方法...(就个人而言,我仍然喜欢后者,因为它通常非常快,只需确保提前删除所有索引/唯一约束并逐个重建它们。这样做的好处是INSERT事务更小,并且稍后再次进行添加索引的操作也是在(较小的)事务中完成的)。

(**:是的,这可能在实时系统上有些棘手,但他已经提到这是在某种过夜期间完成的,我正在推断此时没有用户访问)


(由于某些原因,我无法评论SQLMenace的答案,因此我自己回答)(我猜我在StackOverflow上还太“年轻”了)请仅返回翻译后的文本。 - deroby
SQL Server上的MERGE可以处理INSERT、UPDATE和DELETE。 - THX-1138
哎呀,真的吗!? 我已经习惯叫它UPSERT了,没想到它也支持DELETE... (被困在SQL2k5上,Merge是我日常工作中无法使用的东西之一...)对于错误的建议感到抱歉,在发布之前阅读文档似乎不会对我造成伤害 =( http://technet.microsoft.com/en-us/library/bb510625.aspx - deroby

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接