我可以想到这2个选项,但不确定是否还有其他选项。什么会更快?
DECLARE @dateVar datetime = '20170101';
UPDATE SALESLINE
SET REMAINSALESFINANCIAL= 0
WHERE CONVERT(DATE, CREATEDDATETIME) < CONVERT(DATE, @dateVar)
或
DECLARE @dateVar datetime = '20170101';
UPDATE SALESLINE
SET REMAINSALESFINANCIAL= 0
WHERE CONVERT(DATE, CREATEDDATETIME) < CONVERT(DATE, @dateVar)
AND REMAINSALESFINANCIAL != 0
答案 0 :(得分:2)
假设REMAINSALESFINANCIAL不包含任何NULL
,您可以使用
UPDATE SALESLINE
SET REMAINSALESFINANCIAL = 0
WHERE CREATEDDATETIME < CONVERT(DATE, @dateVar)
AND REMAINSALESFINANCIAL <> 0
由于CONVERT(DATE, @dateVar)
的时间部分为00:00:00
,因此小于的任何日期时间必须包含前一天或更早的日期部分。
将datetime
列投放到date
并不会阻止索引使用,但它是more optimal not to。
答案 1 :(得分:2)
我同意其他答案,第二个选项应该更快,但从性能角度考虑还有其他考虑因素。
如果指定的值具有午夜时间,则不需要显式转换。
我建议查询参数化,以便使用统计直方图代替平均基数来更好地优化查询,而不是局部变量。如果您的实际查询直接使用存储过程参数或从应用程序代码调用参数化查询,则这是自动的。如果参数嗅探是个问题(这里不太可能,恕我直言),请添加OPTION RECOMPILE
查询提示。
EXEC sp_executesql N'
UPDATE SALESLINE
SET REMAINSALESFINANCIAL= 0
WHERE
CREATEDDATETIME < @dateVar
AND REMAINSALESFINANCIAL <> 0;'
, N'@dateVar datetime'
, @dateVar = '20180101';
答案 2 :(得分:1)
第二个版本更好。如果你有一些行REMAINSALESFINANCIAL = 0
,那么引擎甚至不会尝试更新这些行,在过程的早期过滤掉它们。注意:这假定REMAINSALESFINANCIAL
永远不会NULL
。
通常,在WHERE
的列上使用函数是一个坏主意。但是,在这种情况下,SQL Server仍将使用索引,因此这不是问题。
将性能与(CREATEDDATETIME)
与(CREATEDDATETIME, REMAINSALESFINANCIAL)
的索引进行比较会很有趣。在第一种情况下,它必须更加努力地找到要更新的行。在第二种情况下,它必须在更改值时更新索引。