1

とにかく、SQL Server 08 でこの恐ろしく非効率な UDF を最適化する方法はありますか?

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

ありがとうございました

** @value(float) と @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]=@fieldName
  select @FRM = [UT_UN_ID_INTERNAL_UNITS] from dbo.UNIT_TYPES where [UT_ID]=@UT
  select @TO = [UT_UN_ID_DISPLAY_UNITS] from dbo.UNIT_TYPES where [UT_ID]=@UT
  select @FACTOR = [UC_SLOPE] from dbo.UNIT_CONVERSIONS where [UC_UN_ID_UNIT_FROM]=@FRM and [UC_UN_ID_UNIT_TO]=@TO

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

7 に答える 7

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]=@UT
于 2009-04-16T18:05:07.007 に答える
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]=@fieldName)
        )
)
于 2009-04-16T18:05:48.127 に答える
1

ステップ 1 は、各選択を個別に実行し、ボトルネックがどこにあるかを確認することです。

于 2009-04-16T18:04:29.160 に答える
0
BEGIN
  DECLARE @FACTOR float

    select @factor = UC.UC_SLOPE
      from dbo.UNIT_CONVERSIONS UC,
           dbo.UNIT_TYPES       UT,
           dbo.UNIT_FIELDS      UF
      where UF.UF_FIELD=@fieldName
        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
于 2009-04-16T18:11:34.870 に答える
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]=@fieldName

-- Return the result of the function dbo.
RETURN @FACTOR*@value
于 2009-04-16T18:14:27.593 に答える
0

あなたができる小さなこと:

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

正しく読むと、これは次のようになります。

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

 from dbo.UNIT_TYPES where [UT_ID]=@UT 

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

于 2009-04-16T18:07:41.040 に答える
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
于 2009-04-16T18:08:19.637 に答える