6

次のステートメントを変更しUPDATEて、スカラー関数が2回ではなく、1回だけ呼び出されるようにする方法はありますか?

UPDATE a
    SET SomeField = b.SomeField
    FROM TableA AS a
    JOIN TableB b ON b.Link = a.Link
    WHERE b.CostMin <= @Cost * dbo.OneScalarFunction(@CurrencyFrom, b.Currency)
        AND b.CostMax >= @Cost * dbo.OneScalarFunction(@CurrencyFrom, b.Currency)

PS演算子を使用しBETWEENても役に立ちません-SQLServerはとにかくスカラー関数を2回呼び出します。

4

3 に答える 3

5

BETWEEN演算子を試してください。

WHERE functionCall(..) BETWEEN minValue AND maxValue

http://www.w3schools.com/sql/sql_between.asp

于 2012-11-14T12:48:29.430 に答える
5

多くの場合、これは大幅にパフォーマンスが向上しますが、スカラー関数をインラインテーブル値関数に変更する必要があります。

UPDATE
  a
SET
  SomeField = b.SomeField
FROM
  TableA AS a
CROSS APPLY
  dbo.oneInlineTableValuedFunction(@CurrencyFrom, e.Currency) AS ITVF
INNER JOIN
  TableB b
    ON b.Link = a.Link
WHERE
      b.CostMin <= @Cost * ITVF.exchangeRate
  AND b.CostMax >= @Cost * ITVF.exchangeRate

テーブル値関数はテーブルを返しますが、1つのフィールドで1つの行だけを再調整することを選択できます。次に、それをスカラー関数として効果的に使用しています-しかし、SQL Serverが上記のクエリを最適化する方法のすべての利点を得ることができます
...-TVFがインライン(マルチステートメントではない)
の場合-TVFは拡張されますクエリに
-結果は、スカラー関数よりも劇的に優れたパフォーマンス になります


インラインテーブル値関数の例:

CREATE FUNCTION dbo.oneInlineTableValuedFunction (
                      @currencyFrom   VARCHAR(32),
                      @currencyTo     VARCHAR(32)
)
RETURNS TABLE
AS
RETURN (
  SELECT
    exchangeRate
  FROM
    dbo.someTable
  WHERE
        currencyFrom = @currencyFrom
    AND currencyTo   = @currencyTo
)

故意に些細なこと

これに関する投稿例: scalar-functions-inlining-and-performance

あなたがウェブを検索するなら、INLINE CROSS APPLY SCALAR FUNCTION PERFORMANCE私はあなたがもっとたくさん得ると確信しています。

于 2012-11-14T13:02:07.623 に答える
3

BETWEEN(以下のように)を使用してみることができますが、データベースがこれを分割して>=および<=として実行する可能性があるという疑いがあるためテストする必要があります。

UPDATE a
    SET SomeField = b.SomeField
    FROM TableA AS a
    JOIN TableB b ON b.Link = a.Link
    WHERE  @Cost * dbo.OneScalarFunction(@CurrencyFrom, e.Currency) BETWEEN b.CostMin AND b.CostMax
于 2012-11-14T12:49:35.010 に答える