2012-05-03 10 views
2

次のクエリには大きな違いがありますか?SQL:速度の考慮事項:0/1と条件付きアクションの乗算

- SELECT value * coeff from Table 

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

は、私はちょうど&を参照してみてください可能性が知っている、私はあなたが私が作るだろういくつかのテストを逃すことは興味深い様々なDBエンジンはそれを扱うことになるかについて作るために、コメント、およびものを持っていると確信しています。

+0

あなたがここで測定するものを気にしないでください。遅い場合は、アプリケーションのネットワークプロトコルを上に置いた場合のCPU負荷がそれほど高くならない場合があります。 – TomTom

+0

@hvd:申し訳ありませんが、質問に間違いがありました。一定。 –

+0

@CodeByMoonlight - 質問タイトルに応じて係数が「0または1」です – MatBailie

答えて

1

速度に大きな違いはありません。

最低レベルでは、両方の値をCPUのレジスタにロードする必要があります。その後、差は第二は常に4回の操作でおおよそ

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

VS ...

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 

あります。 coefがゼロでない場合、最初は5回の演算です。

しかし、最初のバージョンでは操作が非常に簡単です。 2番目の乗算はより集中的になります。私が知る限り、0または1の整数倍は、あなたが得るのと同じくらい速いです。 VALUEがFloatの場合、より集中的になります。

(これは、すべての基本的な実用的な知識ではなく、任意の専門知識からである。)


すべて言ったが、しかし、差ははるかに少ないディスクからデータをロードするよりもされること、またはtcp/ipでの送信

プロファイラを実行し、それぞれが使用するCPUサイクルを測定する必要があります。時間はかかりません。 1つのバージョンが他のバージョンよりもわずかに少ないCPUしか使用しないことがあります。それでも、取った時間の差はほとんど見られません。

+0

SQLエンジンがそれを翻訳する可能性は全く異なりますたとえば、coeffのインデックスのために、 'SELECT 0 FROM table WHERE coeff = 0 UNION ALL SELECT value FROMテーブルWHERE coeff <> 0'のようなものです。その場合、あなたの答えは実際には機能しません。 – hvd

+0

@hvd - それはこれまでにないでしょう。 * you *がそのようにコードをリファクタリングすることは可能ですが、オプティマイザがそのようなことをしたことは一度もありません。それはあまりにも狭い最適化であり、プログラマに残されたものです。 – MatBailie

+0

"私はオプティマイザがそれ自体をやっていることは経験したことがありません" "それはこれを行うことはありません"を意味するものではありません。テーブルのサイズが十分に大きい場合は、これを変更する必要があります(そうでなければ、気にする必要はありません)。パーティション化されたビューとしてテーブルを設定し、 'coeff'をパーティションの列として設定すると意味がありますチェック制約 'coeff = 0'を持つパーティションテーブルで' WHEN coeff = 0'を最適化しなかった場合、SQL Serverは私を驚かせるでしょう。 – hvd

1

結果のデータ型は、掛け算と大文字列の間に違いがあります。

はSSMS

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

のスクリプトテーブルaaa次に、この

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 

を試してみて明らかに乗算はvalueデータ型の精度/スケールをエスカレート。 CASEは、このような予期しない結果に対してはるかに耐性があります。

関連する問題