该问题可能特定于SQL Server。当我编写查询时,例如:
SELECT * FROM IndustryData WHERE Date='20131231' AND ReportTypeID = CASE WHEN (fnQuarterDate('20131231')='20131231') THEN 1 WHEN (fnQuarterDate('20131231')!='20131231') THEN 4 END;
是否对表的EACH行执行Case内的Case内的函数调用fnQuarterDate(或任何子查询)?
如果我预先在类似这样的变量中获取函数(或任何子查询)的值,会怎么样呢?
DECLARE @X INT IF fnQuarterDate('20131231')='20131231' SET @X=1 ELSE SET @X=0 SELECT * FROM IndustryData WHERE Date='20131231' AND ReportTypeID = CASE WHEN (@X = 1) THEN 1 WHEN (@X = 0) THEN 4 END;
我知道在MySQL中,如果WHERE子句中的IN(..)内有子查询,则对每一行都执行该子查询,我只想为SQL SERVER查找相同的子查询。
…
只需填充约3万行的表,然后发现时差:
Query1 = 70ms; 查询2 = 6毫秒。我认为这可以解释它,但仍然不知道其背后的实际事实。
如果不是一个UDF,而是一个简单的子查询,也会有什么区别吗?
我认为该解决方案在理论上可以帮助您提高性能,但是它也取决于标量函数的实际作用。我认为在这种情况下(我的猜测是将日期格式化为该季度的最后一天)确实可以忽略不计。
您可能需要阅读此页面,并附有建议的解决方法:
http://connect.microsoft.com/SQLServer/feedback/details/273443/the-scalar- expression-function-would-speed-performance-while-keeping-the-benefits-of- functions#
因为SQL Server必须在每一行上执行每个函数,所以使用任何函数都会产生游标,如性能下降。
在变通办法中,有一条评论指出
当我在连接列中使用标量UDF时,我遇到了同样的问题,其性能令人震惊。在我用包含UDF结果的临时表替换了UDF并将其用于join子句后,性能提高了几个数量级。MS团队应修复UDF以使其更可靠。
因此看来,是的,这可能会提高性能。
您的解决方案是正确的,但是我建议您考虑对SQL进行改进以使用ELSE,它对我来说看起来更干净:
AND ReportTypeID = CASE WHEN (@X = 1) THEN 1 ELSE 4 END;