2009-04-16 8 views
1

SQL Server 08でこの恐ろしい非効率なUDFを最適化する方法はありますか?私はUDFにはかなり新しく、特に最適化を検討しています。SQL Serverでこの恐ろしい非効率なユーザー定義関数を最適化する方法08

UPDATE: クエリの各行と各列でこれを実行する場合は、このような関数に列を送信する必要がありますか?これについてもっと良い方法がありますか?

はありがとうございました

** @value(フロート)と@fieldname(VARCHAR(40))されている入力パラメータ**

BEGIN 
    DECLARE @UT integer, @FRM integer, @TO integer, @FACTOR float 

    select @UT = [UF_UT_ID] FROM dbo.UNIT_FIELDS where [UF_FIELD][email protected] 
    select @FRM = [UT_UN_ID_INTERNAL_UNITS] from dbo.UNIT_TYPES where [UT_ID][email protected] 
    select @TO = [UT_UN_ID_DISPLAY_UNITS] from dbo.UNIT_TYPES where [UT_ID][email protected] 
    select @FACTOR = [UC_SLOPE] from dbo.UNIT_CONVERSIONS where [UC_UN_ID_UNIT_FROM][email protected] and [UC_UN_ID_UNIT_TO][email protected] 

    -- Return the result of the function dbo. 
    RETURN @FACTOR*@value 
END 
+0

はどのようにこのUDFは非効率的であることを知っていますか? SQLプロファイラで何かを見ましたか? – MedicineMan

答えて

1

ステップ1は、それぞれが個別に選択して、場所を確認実行することですボトルネックはです。

3

PK/FK関係に基づいて3つのテーブルを結合することができれば、クエリを1つの選択にすることができます。ない場合は、だけですぐに明白な最適化は、単一のSELECT文で@FRMと@TOを割り当てることです:

select @FRM = [UT_UN_ID_INTERNAL_UNITS], @TO = [UT_UN_ID_DISPLAY_UNITS] from dbo.UNIT_TYPES where [UT_ID][email protected] 
2

インライン表関数のための古典的な候補...

何かのように:

ALTER FUNCTION fnName(@value float, @fieldName VARCHAR(100)) 
RETURNS TABLE 
AS 
RETURN 
(
    SELECT @value * 
     (SELECT conv.[UC_SLOPE] from dbo.UNIT_CONVERSIONS conv 
     JOIN dbo.UNIT_TYPES UT_UN_ID_INTERNAL_UNITS ON where [UC_UN_ID_UNIT_FROM]=UT_UN_ID_INTERNAL_UNITS.[UT_ID] 
     JOIN dbo.UNIT_TYPES UT_UN_ID_DISPLAY_UNITS ON where [UC_UN_ID_UNIT_TO]=UT_UN_ID_DISPLAY_UNITS.[UT_ID] 
     JOIN dbo.UNIT_FIELDS fields ON (UT_UN_ID_INTERNAL_UNITS.[UT_ID] = fields.[UF_UT_ID]) AND (UT_UN_ID_DISPLAY_UNITS.[UT_ID] = fields.[UF_UT_ID]) 
     WHERE ([UF_FIELD][email protected]) 
     ) 
) 
0

一つの小さなことを行うことができます:

select @FRM = [UT_UN_ID_INTERNAL_UNITS] from dbo.UNIT_TYPES where [UT_ID][email protected] 
select @TO = [UT_UN_ID_DISPLAY_UNITS] from dbo.UNIT_TYPES where [UT_ID][email protected] 

私が読んでいる場合、正しく、これは希望

select @TO = [UT_UN_ID_DISPLAY_UNITS], 
     @FRM = [UT_UN_ID_INTERNAL_UNITS] 

from dbo.UNIT_TYPES where [UT_ID][email protected] 

なぜ同じレコードで選択を2回実行するのですか?

0

これはJOIN年代を使って書き直す必要があります:

SELECT c.UC_SLOPE * @value 
FROM unit_fields f 
JOIN unit_types t 
ON  t.UT_ID = f.UF_UT_ID 
JOIN unit_conversions c 
ON  c.UC_UN_ID_UNIT_FROM = t.UT_UN_ID_INTERNAL_UNITS 
     AND c.UC_UN_ID_UNIT_TO = t.UT_UN_ID_DISPLAY_UNITS 
WHERE f.UF_FIELD = @field_name 
0
BEGIN 
    DECLARE @FACTOR float 

    select @factor = UC.UC_SLOPE 
     from dbo.UNIT_CONVERSIONS UC, 
      dbo.UNIT_TYPES  UT, 
      dbo.UNIT_FIELDS  UF 
     where [email protected] 
     and UT.UT_ID = UF.UF_UT_ID 
     and UC.UC_UN_ID_UNIT_FROM = UT.UT_UN_ID_INTERNAL_UNITS 
     and UC.UC_UN_ID_UNIT_TO = UT.UT_UN_ID_DISPLAY_UNITS 


    -- Return the result of the function dbo. 
    RETURN @FACTOR*@value 
END 
0

あなたはすべて1つのクエリとしてこれを試すことができます。

--Decalre Factor var 
DECLARE @FACTOR float 

SELECT @FACTOR = [UC_SLOPE] 
FROM dbo.UNIT_CONVERSIONS uc 
--Join the Unit Types table to Unit Conversions on the old From & To types 
INNER JOIN dbo.UNIT_TYPES ut ON 
    ut.[UT_UN_ID_DISPLAY_UNITS] = uc.[UC_UN_ID_UNIT_TO] 
    AND ut.[UT_UN_ID_INTERNAL_UNITS] = uc.[UC_UN_ID_UNIT_FROM] 
--Join the Unit Files on the Unit Types 
INNER JOIN dbo.UNIT_FIELDS uf ON 
    uf.[UF_UT_ID] = ut.[UT_ID] 
WHERE uf.[UF_FIELD][email protected] 

-- Return the result of the function dbo. 
RETURN @FACTOR*@value 
関連する問題