什么比较方法比较好?
我的表中有一个触发器,其中有大量列(可能大约 100 个)和相当多的更新(对于“很多”的某些定义)。 如果任何字段发生更改,触发器将在另一个表中插入一些数据。
出于显而易见的原因,我希望这个触发器尽可能快地运行。进行比较的最佳方法是什么? 现在我有这些:
IF NOT EXISTS (SELECT * FROM Inserted i, Deleted d WHERE
i.Fld1 = d.Fld1 AND i.Fld2 = d.Fld2 AND
i.Fld3 = d.Fld3 AND i.Fld4 = d.Fld4 AND
i.Fld5 = d.Fld5 AND i.Fld6 = d.Fld6 AND
i.Fld7 = d.Fld7)
THEN ...
IF ((SELECT Fld1 FROM Inserted) <> (SELECT Fld1 FROM Deleted) OR
(SELECT Fld2 FROM Inserted) <> (SELECT Fld2 FROM Deleted) OR
(SELECT Fld3 FROM Inserted) <> (SELECT Fld3 FROM Deleted) OR
(SELECT Fld4 FROM Inserted) <> (SELECT Fld4 FROM Deleted) OR
(SELECT Fld5 FROM Inserted) <> (SELECT Fld5 FROM Deleted) OR
(SELECT Fld6 FROM Inserted) <> (SELECT Fld6 FROM Deleted) OR
(SELECT Fld7 FROM Inserted) <> (SELECT Fld7 FROM Deleted))
THEN...
我通常更喜欢第一种方法,因为它更紧凑并且看起来更惯用。但是,当速度成为问题时,我该怎么办?
I have a trigger in a table with a good number of columns (perhaps around 100) and quite a lot of updates (for some definition of "a lot of").
If any of some fields have changed, the trigger inserts some data in another table.
For obvious reasons, I want this trigger to run as fast as possible. What's the best method to do the comparison?
For now I have those:
IF NOT EXISTS (SELECT * FROM Inserted i, Deleted d WHERE
i.Fld1 = d.Fld1 AND i.Fld2 = d.Fld2 AND
i.Fld3 = d.Fld3 AND i.Fld4 = d.Fld4 AND
i.Fld5 = d.Fld5 AND i.Fld6 = d.Fld6 AND
i.Fld7 = d.Fld7)
THEN ...
IF ((SELECT Fld1 FROM Inserted) <> (SELECT Fld1 FROM Deleted) OR
(SELECT Fld2 FROM Inserted) <> (SELECT Fld2 FROM Deleted) OR
(SELECT Fld3 FROM Inserted) <> (SELECT Fld3 FROM Deleted) OR
(SELECT Fld4 FROM Inserted) <> (SELECT Fld4 FROM Deleted) OR
(SELECT Fld5 FROM Inserted) <> (SELECT Fld5 FROM Deleted) OR
(SELECT Fld6 FROM Inserted) <> (SELECT Fld6 FROM Deleted) OR
(SELECT Fld7 FROM Inserted) <> (SELECT Fld7 FROM Deleted))
THEN...
I would usually prefer the first method, as it's more compact and seems more idiomatic. However, when speed is an issue, how should I do it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
第二个版本对于多行更新来说完全被破坏了,所以仅出于这个原因,我会做第一个版本的变体:
假设 PK 是稳定且不变的
The second version is completely broken for multi-row UPDATES, so for that reason alone, I'd do a variant of the first:
Assuming the PK is stable and unchanging
为什么不使用
IF UPDATE(Column1,Column2,...)
测试更改的列,这会让您知道您感兴趣的列是否已更改。请参阅 < a href="http://msdn.microsoft.com/en-us/library/ms187326.aspx" rel="nofollow">http://msdn.microsoft.com/en-us/library/ms187326.aspx< /a> 有关UPDATE()
函数的详细信息。如果 PK 已被修改,您也可以使用它,而在
插入
和删除
之间进行比较时,您尝试执行的方式将会错过关于PK的改动。除非您在比较之前
SET ANSI_NULLS OFF
,否则涉及测试所有字段的不等式的解决方案将会失败。例如:
当然,您可以进行额外的测试,而不是使用
ansi_nulls
选项,但如果您对许多字段执行此操作,情况会变得特别疯狂。另外:您必须在创建触发器之前设置 ansi_nulls off
- 您无法在触发器内打开和关闭它,因此整个事物必须具有相同的ansi_nulls
设置。Why don't you test your changing columns by using
IF UPDATE(Column1,Column2,...)
That will let you know whether any of the columns have changed that you're interested in. See http://msdn.microsoft.com/en-us/library/ms187326.aspx for details on theUPDATE()
function.You'll also be able to use it if the PK has been modified, whereas comparing between the
inserted
anddeleted
the way you're trying to go about it will miss out on changes to the PK.The solution involving testing the inequality of all of the fields will fail unless you
SET ANSI_NULLS OFF
before comparing.For example:
Of course, you could put in additional tests rather than going with the
ansi_nulls
option, but that gets particularly crazy if you're doing this with many fields. Also: you mustset ansi_nulls off
prior to creating the trigger - you can't turn it on and off inside the trigger, so the whole thing must have the sameansi_nulls
setting.