インラインTVFとビューのパフォーマンス


9

ビューの代わりにインラインTVF(テーブル値関数)を使用しているデータベースがあります。たとえば、TVF [fnCarBrands]内で結合している[車のモデル]と[車のメーカー]という2つのテーブルがあるとします。

これらのTVFは他のTVFから呼び出され、さらに処理とレポートを行います。したがって、関数[fnCarBrands]を受け取り、テーブル[購入年]に結合して、関数[fnCarBrandHistory]を作成します。TVFのいくつかの層についても同様です。

インラインTVFは実際にはテーブルと他のTVFの単なる結合なので、おそらくビューを使用して同じ機能を取得できます。

このように記述されたインラインTVFのパフォーマンスは、ビューとどのように比較されますか?


ほとんどの場合、同じ実行プランと同じパフォーマンスが表示されます。
AK

それは私が思っていたものですが、TVFは代数の括弧のように振る舞うと言われました-最適化する前に、DBエンジンが最初にそのクエリを完了するよう強制します。ビューを使用すると、オプティマイザはクエリ全体を1つの単位として最適化できます。
FistOfFury

余談ですが、ビューの代わりにTVFが使用された理由は何ですか?問題に対するコードモンキーデータモンキーのアプローチだけですか?
Mark Storey-Smith

@ MarkStorey-Smithはい、理由はあなたが言うように、コードモンキー対データモンキーアプローチです。
FistOfFury 2012

回答:


12

クエリオプティマイザーは、インラインテーブル値関数をビューのように扱います。

CREATE FUNCTION dbo.InlineUdf(@arg1 int)
RETURNS TABLE
AS
RETURN 
(
    ... your query here ...
);

複数ステートメントのテーブル値関数は、より多くのストアドプロシージャのように実行されます。これらは通常、メインのクエリに組み込まれるのではなく、複数回実行する必要があります。

CREATE FUNCTION dbo.MultiStatementUdf (@col1 int)
RETURNS @result TABLE 
(
    id int primary key NOT NULL,
    ... 
)
AS
BEGIN
   DECLARE @var1 int
   set @var1 = 42

   INSERT @result
   SELECT ...
   RETURN
END;

1
@Andomar私の理解では、マルチステートメントTVFはブラックボックスのように実行され、エンジンは何が入っているかを認識しておらず、クエリを最適化できません。ビューとインラインTVFが同等であると言及できる記事はありますか?
FistOfFury

4

関数と同様のビューを作成し、実行プランを見てそれぞれにクエリを実行し、それぞれで何が起こっているかを確認する必要があります。


丁度。ベンチマーク、自分の目で確かめる-これが唯一の信頼できる学習方法です。
AK

@mrdennyオプティマイザが各タイプのクエリをどのように処理するかを予測する方法はありませんか?確かにそれに従ういくつかのルールがあります。
FistOfFury

2
@FistOfFuryはい、ルールがあり、何千ものルールがあり、何百年もの開発者によるヒューリスティックコードで補完されています。これが、テストするか、Microsoftにオプティマイザのソースコードを要求する必要がある理由です。
Mark Storey-Smith

データベースエンジンが何をすべきかをどのように決定するかを理解したい場合は、SQL Serverの内部、amazon.com
s /…

3

もちろん、他のビューを呼び出すビューを作成することも、パフォーマンスの向上につながります。そのルートを下らないでください。必要なクエリを記述し、パフォーマンスが必要な場合はTVFもビューも使用しないでください。これは、あるレイヤーあなたが頻繁に参照終わる特に以来、これはほとんど常にデータベースを照会したときに行うには悪いことであり、あなたはすぐにあなたも参照できるテーブルの数の制限に達してしまうことができ、問題を作成しています異なるレイヤーの同じテーブル。さらに、これは保守が容易であるように見えますが、そうではありません。修正する必要のあるレイヤーが最下部にある場合は、新しい要件のためにデバッグまたは列の追加を試してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.