以下查询之间是否存在显着的速度差异?SQL:速度考虑因素:乘以0/1与条件操作
- SELECT value * coeff from Table
- SELECT CASE WHEN coeff = 0 THEN 0 ELSE value END FROM Table
我知道我可以只是尝试&看到,但我相信你将有有趣的评论作出关于各种数据库引擎将如何处理,以及事情的几个测试我会做会想念。
以下查询之间是否存在显着的速度差异?SQL:速度考虑因素:乘以0/1与条件操作
- SELECT value * coeff from Table
- SELECT CASE WHEN coeff = 0 THEN 0 ELSE value END FROM Table
我知道我可以只是尝试&看到,但我相信你将有有趣的评论作出关于各种数据库引擎将如何处理,以及事情的几个测试我会做会想念。
不会有任何显着的速度差异。
在最低级别,您需要将两个值加载到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比其他版本少一点。而且总时间几乎没有差别。
一个完全不同的可能性是SQL引擎翻译它例如,在读取任何行之前,例如,由于SELECT FOR FROM表WHERE coeff = 0 UNION ALL SELECT值FROM表WHERE coeff <> 0',例如因为coeff上的索引。在这种情况下,你的答案并不真正起作用。 – hvd
@ hvd - 它永远不会那样做。你可能以这种方式重构代码,但我从来没有经历过优化器自己做这件事。这只是一个过于狭窄的优化,而剩下的就是程序员。 – MatBailie
“我从来没有经历过这种优化器本身”并不意味着“它永远不会这样做”。当这些表足够大时(或者,你真的不应该在乎,正如你也注意到的那样),将表设置为分区视图可能是有意义的,'coeff'作为分区列,如果SQL Server没有在检查约束'coeff = 0'的分区表中优化'WHEN coeff = 0',我会感到惊讶。 – hvd
乘法和大小写列之间的结果数据类型可能有所不同。
试试这个
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
对此类意外结果的抵抗力要强大得多。
小心你在这里测量。考虑到你有一个网络协议到最上面的应用程序,速度更慢可能会导致更多的CPU负载。 – TomTom
@ hvd:对不起,我在查询中犯了一个错误。固定。 (你理解了这个想法) –
@CodeByMoonlight - 根据问题标题 – MatBailie