2012-05-03 30 views
2

以下查询之间是否存在显着的速度差异?SQL:速度考虑因素:乘以0/1与条件操作

- SELECT value * coeff from Table 

- SELECT CASE WHEN coeff = 0 THEN 0 ELSE value END FROM Table 

我知道我可以只是尝试&看到,但我相信你将有有趣的评论作出关于各种数据库引擎将如何处理,以及事情的几个测试我会做会想念。

+0

小心你在这里测量。考虑到你有一个网络协议到最上面的应用程序,速度更慢可能会导致更多的CPU负载。 – TomTom

+0

@ hvd:对不起,我在查询中犯了一个错误。固定。 (你理解了这个想法) –

+0

@CodeByMoonlight - 根据问题标题 – MatBailie

回答

1

不会有任何显着的速度差异。

在最低级别,您需要将两个值加载到CPU中的寄存器中。那么,这种差异大致...

Load coeff into register1 
Load value into register2 
If register1 is not 0, skip the next operation 
Load 0 into register2 
Return value in register2 

VS

Load coeff into register1 
Load value into register2 
register2 = register1 * register2 
Return value in register2 

二是始终为4点的操作。当coef非零时,第一个是5次操作。

但是第一个版本的操作非常简单。第二次乘法将更加密集。据我所知,0或1的整数乘法仍然和你一样快。但是,如果VALUE是一个浮点数,它将更加密集。

(这是所有从基本操作知识,没有任何专业知识。)


这一切说,然而,差别会比从磁盘加载数据要少得多,或通过tcp/ip传输。

您应该运行一个分析器并测量每个CPU使用的CPU周期。不是所花的时间。你可能会发现你使用的CPU比其他版本少一点。而且总时间几乎没有差别。

+0

一个完全不同的可能性是SQL引擎翻译它例如,在读取任何行之前,例如,由于SELECT FOR FROM表WHERE coeff = 0 UNION ALL SELECT值FROM表WHERE coeff <> 0',例如因为coeff上的索引。在这种情况下,你的答案并不真正起作用。 – hvd

+0

@ hvd - 它永远不会那样做。你可能以这种方式重构代码,但我从来没有经历过优化器自己做这件事。这只是一个过于狭窄的优化,而剩下的就是程序员。 – MatBailie

+0

“我从来没有经历过这种优化器本身”并不意味着“它永远不会这样做”。当这些表足够大时(或者,你真的不应该在乎,正如你也注意到的那样),将表设置为分区视图可能是有意义的,'coeff'作为分区列,如果SQL Server没有在检查约束'coeff = 0'的分区表中优化'WHEN coeff = 0',我会感到惊讶。 – hvd

1

乘法和大小写列之间的结果数据类型可能有所不同。

试试这个

CREATE TABLE #Tmp (value DECIMAL(19, 2), coeff BIT) 

INSERT #Tmp SELECT 15, 1 
INSERT #Tmp SELECT 16, 0 

SELECT value * coeff AS final_value_mult 
     , CASE WHEN coeff = 0 THEN 0 ELSE value END AS final_value_case 
INTO aaa 
FROM #Tmp 

--DROP TABLE aaa, #Tmp 

然后脚本表aaa在SSMS

CREATE TABLE [dbo].[aaa](
    [final_value_mult] [decimal](38, 4) NULL, 
    [final_value_case] [decimal](19, 2) NULL 
) ON [PRIMARY] 

显然乘法升级精度/的value数据类型的规模。 CASE对此类意外结果的抵抗力要强大得多。