2009-08-19 23 views
3

SQLが直接インライン化された場合に発生しないSQL Server 2008のインラインテーブル値関数を使用するための固有のコストはありますか?私たちのアプリケーションは、一般的なクエリを再利用するためにインラインテーブル値関数を非常に重視していますが、最近では、クエリを使用しないとクエリの実行速度が大幅に向上しています。私はこれを行う際に、今SQL Serverのインラインテーブル評価関数のコスト

CREATE FUNCTION dbo.fn_InnerQuery (@asOfDate DATETIME) 
RETURNS TABLE 
AS 
RETURN 
(
    SELECT ... -- common, complicated query here 
) 

SELECT TOP 10 Amount FROM dbo.fn_InnerQuery(dbo.Date(2009,1,1)) ORDER BY Amount DESC 

クエリは約15秒で結果を返します

が、この考えてみましょう。しかし

、私はこれを行う:1秒未満で

SELECT TOP 10 Amount FROM 
(
    SELECT ... -- inline the common, complicated query here 
) inline 
ORDER BY Amount DESC 

クエリ戻ります。

この場合、テーブル値関数を使用するオーバーヘッドに少し困惑します。それを予想しなかった。私たちのアプリケーションでは、大量のテーブル機能を持​​っていますので、私がここで欠けているものがあるかどうか疑問に思っています。

答えて

3

この場合、UDFはビューのようにネストされていない/展開されている必要があり、透明でなければなりません。明らかに

、それはありません...この場合

、私の推測では、列が(columのデータ型と一致する)ときsmalldatetime型であると理由UDFパラメータのdatetime型にキャストされますが、定数が正しく評価されていることです列をなして。

日時はSMALLDATETIME高い優先順位を持っているので、列は、クエリプランは何を言う

をキャストすることでしょうか? UDFはインラインaが(ちょうど私が前に見たものに基づいて、100%ではない)可能性が高いを求め、スキャンを示すだろう

編集:Blog post by Adam Machanic

+0

gbn、リンクをありがとう。私はそれをもっと深く見なければならないでしょう。 UDFの実行計画はインラインバージョンよりはるかに複雑ですが、なぜそうであるのかはっきりしていません。どのようにパラメータを渡すと動作が変わるように見えますか? SELECT TOP 10金額からdbo.fn_InnerQuery(dbo.Date(2008,7,24))注文数量 が15秒で実行されます。 SELECT TOP 10金額dbo.fn_InnerQuery( '7/24/2008')注文数量 は1未満で実行されます。 – Linus

+0

'2008年7月24日'を使用してからdbo.Date(2008、 7,24)インライン? – gbn

0

機能を低下させる原因の1つは、dboを省略することです。関数内のテーブル参照から取得します。そのため、SQL Serverはすべての呼び出しに対してセキュリティチェックを行いますが、これは高価になる可能性があります。

+3

コンパイル時または再使用時のみ。次回の実行(同じクエリ、同じユーザーなど)でも問題ありません。 – gbn

+1

dboは省略しません。そうであってはならない。また、たとえオーバーヘッドがあったとしても、14秒のオーバーヘッドになるとは思わないでしょう。 – Linus

0

見るために独立して、テーブル値関数を実行してみてください、どのように高速/低速で実行しますか?

また、SQL ServerがUDFの実行によって保持する実行キャッシュ(?)をクリアする方法がわかりません。つまり、最初にUDFを実行すると、SQL Serverに実際のクエリがあり、&というプラン/結果がキャッシュされる場合があります。したがって、複雑なクエリを別々に実行すると、キャッシュから実行されている可能性があります。

+0

実行キャッシュをクリアします。 DBCC FREEPROCCACHE –

0

2番目の例では、テーブル値関数は、クエリがフィルタを適用する前にデータセット全体を返す必要があります。 TF境界を横切ってホッピングすることは、オプティマイザが常に行うことができるものではありません。

第3の例では、クエリオプティマイザは、ユーザーが上位の「金額」しか必要としないことを確認できます。これが集計値でない場合、オプティマイザはその処理をクエリの最初にプッシュし、他のデータを気にする必要はありません。それが総額の場合、減速は別の理由によるものです。

2つのクエリのクエリプランを比較すると、それらが異なることがわかります。

+0

これは、複数のステートメントテーブル値関数にのみ適用されます。それが起こると、あなたは内なる計画を見ることができません。あなたはSQLプロファイラからIOとCPUを推論することしかできません – gbn