次のクエリ間で速度に大きな違いはありますか?
- SELECT value * coeff from Table
- SELECT CASE WHEN coeff = 0 THEN 0 ELSE value END FROM Table
試してみることができることはわかっていますが、さまざまなDBエンジンがそれをどのように処理するか、および私が行ういくつかのテストでは見逃されることについて、興味深いコメントがあると確信しています.
次のクエリ間で速度に大きな違いはありますか?
- SELECT value * coeff from Table
- SELECT CASE WHEN coeff = 0 THEN 0 ELSE value END FROM Table
試してみることができることはわかっていますが、さまざまなDBエンジンがそれをどのように処理するか、および私が行ういくつかのテストでは見逃されることについて、興味深いコメントがあると確信しています.
速度に大きな違いはありません。
最も低いレベルでは、両方の値を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
2番目は常に4つの操作です。1つ目は、coefがゼロ以外の場合の5つの操作です。
しかし、最初のバージョンの操作は非常に簡単です。2番目の乗算はより集中的になります。私の知る限り、0または1の整数乗算は、それでもほぼ同じくらい高速です。ただし、VALUEがFloatの場合は、より集中的になります。
(これはすべて基本的な実務知識によるものであり、専門知識によるものではありません。)
とはいえ、違いはディスクからのデータのロードやtcp/ipを介した送信よりもはるかに小さいでしょう。
プロファイラーを実行し、それぞれが使用するCPUサイクルを測定する必要があります。かかった時間ではありません。あるバージョンでは、他のバージョンよりもCPUの使用量がわずかに少ない場合があります。それでも、合計所要時間にほとんど違いは見られません。
乗算列とケース列では、結果のデータ型が異なる場合があります。
これを試して
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
そのような予期しない結果の影響をはるかに受けません。