SQLSererネタ:WHERE句にユーザー関数はご法度の巻き

SQLServerの中古1年生である、わたしは「処理時間がかかりすぎ」
ということで、色々調査をしていた時にSQLエリアナライザに
[実行プラン]なるものがあることに気がつき、そのおかげで
ボトルネックを解消してから、やみつき状態に。
ある時、ボトルネックを調査していたら、あるパターンの
ネックがあることが判明した。それは、
「WHERE句にユーザー定義関数がある場合」であった。
下記のテストを見て頂こう。
[テーブル]
CREATE TABLE [TAB_Test_Where_Function] (
[Col1] [varchar] (50) COLLATE Japanese_BIN NULL
) ON [PRIMARY]

[ユーザー定義関数]
CREATE FUNCTION UDF_Test_Where_Function(@Value AS INT)
RETURNS INT
AS
BEGIN
SET @Value = @Value + 1
RETURN (@Value)
END

[ストアドプロシージャ]
CREATE PROCEDURE PRC_Test_Where_Function
AS
SELECT * FROM TAB_Test_Where_Function WHERE Col1 = dbo.UDF_Test_Where_Function(1)

上記のテスト環境を作成した後に、[TAB_Test_Where_Function].[Col1]に
データを入れる。
[Col1]
100
200
300
とりあえず3件入れて、デバッグをしてみた。
すると、

ユ ー ザ ー 定 義 関 数 を 3 回 通 っ て い る

ではないかぁーΣ(゜д゜lll)ガーン
さらに2件増やしてテストすると、5回通っていることを確認した。
つまり、WHERE句にユーザー定義関数を設定すると、

デ ー タ 件 数 分 ユ ー ザ ー 定 義 関 数 
 を 通 っ て し ま う

っちゅーこっちゃ。Σ(゜д゜)オイオイ
というよりも、わたし自身がユーザー定義関数を勘違いしている
可能性が大である。てっきり「ユーザー関数は1回しか通らない」
と思い込んでいたのが敗因かと思われる。
ちなみに今回ボトルネックだったパターンは、

DELETE FROM TAB_Hoge WHERE Col = UDF_MaeZero(@intValue, 12)

というケースだった。UDF_MaeZero(@intValue, 12)の部分は固定で良い
ので、

SET @vchValue = UDF_MaeZero(@intValue, 12)
DELETE FROM TAB_Hoge WHERE Col = @vchValue

というパターンでボトルネックを回避できた。
使いどころや勘違いに要・注意。ウフ♪(* ̄ー ̄)v
と思った今日この頃。SQLServerは奥が深いのぉ。