--ストアドファンクション高速化
--ストアドファンクションでWHERE条件で条件を絞る場合
--パラメータで渡ってくる変数をそのままWHERE文で使う場合よりも
--パラメータで渡ってくる変数を一度、ストアドファンクションで宣言した変数
--に代入してから代入した変数をWHERE文で使う方が処理が速くなる。
--なぜそうなるのか原因はわかりませんが、実際に処理させるとそうなりました。
--SAMPLEの例では処理速度はそんなに変わらないかもしれませんが、同じパラメータの値で
--何度も条件を絞り、なおかつデータ量が多い場合は高速化します。
--パラメータの変数は一度、別の変数に入れましょう。
--悪い例
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[SAMPLE01SF]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
DROP FUNCTION [dbo].[SAMPLE01SF]
GO
CREATE FUNCTION [dbo].[SAMPLE01SF]
-- パラメータ宣言
(
@IN_SHORIDATE CHAR(8)
)
RETURNS
-- 戻り値格納用
@RETURN_TABLE TABLE
(
ReturnChi DECIMAL(4,3)
)
AS
BEGIN
-- 処理開始
PROC_START:
INSERT INTO @RETURN_TABLE
SELECT TOP 1
ReturnChi
FROM
SampleTable
WHERE
ShoriNO = '01'
AND ShoriDate = @IN_SHORIDATE --←パラメータの変数をそのまま使う(×)
IF @@ROWCOUNT = 0
BEGIN
INSERT INTO @RETURN_TABLE VALUES ( 0.0 )
END
-- 処理終了
PROC_END:
RETURN
END
--良い例
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[SAMPLE01SF]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
DROP FUNCTION [dbo].[SAMPLE01SF]
GO
CREATE FUNCTION [dbo].[SAMPLE01SF]
-- パラメータ宣言
(
@IN_SHORIDATE CHAR(8)
)
RETURNS
-- 戻り値格納用
@RETURN_TABLE TABLE
(
ReturnChi DECIMAL(4,3)
)
AS
BEGIN
-- 変数宣言
DECLARATION:
DECLARE @sSHORIDATE CHAR(8)
-- 処理開始
PROC_START:
SET @sSHORIDATE = @IN_SHORIDATE --←一度、別の変数に代入(○)
INSERT INTO @RETURN_TABLE
SELECT TOP 1
ReturnChi
FROM
SampleTable
WHERE
ShoriNO = '01'
AND ShoriDate = @sSHORIDATE --←代入した変数を使う(○)
--以下で同じ変数の条件を使う場合は@sSHORIDATEを使う
IF @@ROWCOUNT = 0
BEGIN
INSERT INTO @RETURN_TABLE VALUES ( 0.0 )
END
-- 処理終了
PROC_END:
RETURN
END
--ストアドファンクションでWHERE条件で条件を絞る場合
--パラメータで渡ってくる変数をそのままWHERE文で使う場合よりも
--パラメータで渡ってくる変数を一度、ストアドファンクションで宣言した変数
--に代入してから代入した変数をWHERE文で使う方が処理が速くなる。
--なぜそうなるのか原因はわかりませんが、実際に処理させるとそうなりました。
--SAMPLEの例では処理速度はそんなに変わらないかもしれませんが、同じパラメータの値で
--何度も条件を絞り、なおかつデータ量が多い場合は高速化します。
--パラメータの変数は一度、別の変数に入れましょう。
--悪い例
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[SAMPLE01SF]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
DROP FUNCTION [dbo].[SAMPLE01SF]
GO
CREATE FUNCTION [dbo].[SAMPLE01SF]
-- パラメータ宣言
(
@IN_SHORIDATE CHAR(8)
)
RETURNS
-- 戻り値格納用
@RETURN_TABLE TABLE
(
ReturnChi DECIMAL(4,3)
)
AS
BEGIN
-- 処理開始
PROC_START:
INSERT INTO @RETURN_TABLE
SELECT TOP 1
ReturnChi
FROM
SampleTable
WHERE
ShoriNO = '01'
AND ShoriDate = @IN_SHORIDATE --←パラメータの変数をそのまま使う(×)
IF @@ROWCOUNT = 0
BEGIN
INSERT INTO @RETURN_TABLE VALUES ( 0.0 )
END
-- 処理終了
PROC_END:
RETURN
END
--良い例
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[SAMPLE01SF]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
DROP FUNCTION [dbo].[SAMPLE01SF]
GO
CREATE FUNCTION [dbo].[SAMPLE01SF]
-- パラメータ宣言
(
@IN_SHORIDATE CHAR(8)
)
RETURNS
-- 戻り値格納用
@RETURN_TABLE TABLE
(
ReturnChi DECIMAL(4,3)
)
AS
BEGIN
-- 変数宣言
DECLARATION:
DECLARE @sSHORIDATE CHAR(8)
-- 処理開始
PROC_START:
SET @sSHORIDATE = @IN_SHORIDATE --←一度、別の変数に代入(○)
INSERT INTO @RETURN_TABLE
SELECT TOP 1
ReturnChi
FROM
SampleTable
WHERE
ShoriNO = '01'
AND ShoriDate = @sSHORIDATE --←代入した変数を使う(○)
--以下で同じ変数の条件を使う場合は@sSHORIDATEを使う
IF @@ROWCOUNT = 0
BEGIN
INSERT INTO @RETURN_TABLE VALUES ( 0.0 )
END
-- 処理終了
PROC_END:
RETURN
END