3

多くのデータ操作と計算を伴う長時間実行プロセスを含む、多数の UDF を含むデータベースがあります。

UDF を使用する際の私の考えは、基礎となるテーブルから情報の論理単位を分離することです。たとえば、車に関する情報を取得しようとしている場合、色、モデル、年式などの複数のテーブルがあり、車を取得するたびに参加する必要があります。代わりに、fnCar() のような関数を使用して、データの非正規化ビューを取得します。

私は長時間実行しているプロセス中にこれらの関数を頻繁に呼び出しますが、代わりに非正規化された作業テーブル、ビュー、または一時テーブルを使用してデータ操作と計算を行う方がよいかどうか疑問に思っています。一般的に UDF を使用する場合、パフォーマンスに関して注意すべき欠点はありますか?

たとえば、UDF を使用していくつかの計算を行います。次に、そのデータのピボットを解除してテーブルに保存します。そのデータを再度使用する必要があるときはいつでも、UDF を呼び出してデータを元に戻します。このようにする理由は、計算を柔軟に保つためです。計算を追加/削除/変更する場合、データ モデルを変更したくありません。

--Calculate some values in a function

declare @location table
(
    id int,
    lattitude float,
    longitude float
)

insert into @location select  1, 40.7, 74
insert into @location select  2, 42, 73
insert into @location select  3, 61, 149
insert into @location select  4, 41, 87


declare @myLattitude float
declare @myLongitude float
set @myLattitude =43
set @myLongitude = 116

declare @distance table
(
    id int,
    distance float
)

insert into @distance
select id, sqrt(power(lattitude-@mylattitude,2)+power(longitude-@mylongitude,2))
from @location



--Store unpivoted data in a table
declare @unpivot table
(
    id int,
    attribute varchar(100),
    attributeValue float
)

insert into @unpivot
(
    id,
    attribute,
    attributeValue
)
select id
    ,attribute
    ,attributevalue 
from
(
    select 
        L.id,
        L.Lattitude, 
        L.Longitude,
        D.Distance
    from @location L 
        inner join @distance D 
        on L.id=D.id
) a
unpivot 
(
    attributeValue for attribute in
    (lattitude, longitude, distance)
) x

--retrive data from store via pivoting function for reporting

select * 
from @unpivot
pivot 
(
    max(attributeValue) for Attribute in (lattitude, longitude, distance)

) x
4

1 に答える 1

6

答えてみます

簡単に言うと、UDFで間違ったことをしている

UDFを使用する場合、これらの問題を追加します

  1. RBAR(下を参照)処理
    SELECT句でテーブルアクセスを使用してスカラーUDFを使用する場合、
    つまり、効率的なJOINの代わりに、テーブルルックアップを*行ごとに強制します。 "

  2. マルチステートメントTVFを使用したブラックボックス処理
    各TVFは完了するまで実行する必要があり、「ブラックボックス」と見なされます。

通常は、フラットなステージングテーブルをロードしてから、JOINを使用してテーブルをルックアップし、処理はセットとして実行されます。これが「非正規化」の意味である場合は、はい、おそらくより適切に機能します。

「情報の論理単位」にUDFを使用することは、OO/手続き的思考です。SQLはセットベースです。ネイティブ/CLRコードで実行されているオブジェクトまたはオブジェクトのコレクションに対して正常と思われるものは、クエリオプティマイザーを介したセットベースのデータ処理では失敗します。

注:RBAR = Row ByAgonizingRow。詳細については、SimpleTalkの記事を参照してください。

于 2012-08-10T14:12:23.870 に答える