SQL Sentry Plan ExplorerはUDFの読み取りをカウントしますか?


9

次のようなクエリがあります。

select dbo.fn_complexFunction(t.id)
from mytable t

SQL Sentry Plan Explorerで、クエリプランにUDFを含めるには、SQL SentryでGet Estimated Planを実行する必要があることに気付きました。

「実際のプランを取得」を実行すると、論理読み取りやその他のメトリックにUDFで発生する操作が含まれているように見えません。このような場合、プロファイラーを使用する唯一の回避策はありますか?


1
私の知る限りでは、クエリエンジン自体はUDFの読み取りを考慮に入れていません。これは、UDFが回避するのに適した大きな理由であり、オプティマイザには不透明です。
JNK、

回答:


11

明らかな免責事項:私はSQL Sentryで働いています

私たちが抱えている最大の問題は次のとおりです。

  1. @JNKが言うように、SQL ServerはUDFの使用を難読化し、とにかくひどいことをします(常に1行を推定するように)。SSMSで実際のプランを生成しても、その使用法はまったくわかりません。SQL Serverが提供するプランに関する情報しか提供できないため、同じ制限を受けます。
  2. 実際の計画を生成するとき、ランタイムメトリックのさまざまなソースに依存しています。残念ながら、プランのXMLには関数呼び出しが含まれておらず、SQL ServerはSET STATISTICS IO ON;どちらかを使用するときに関数によって発生するI / Oを明らかにしません(これがTable I/Oタブの設定方法です)。

AdventureWorks2012に対する次のビューと機能を検討してください。これは、ヘッダーテーブルからランダムな行が与えられた場合、詳細テーブルからランダムな行を返すというばかげた試みです。ほとんどの場合、毎回可能な限り多くのI / Oを生成するためです。

CREATE VIEW dbo.myview 
WITH SCHEMABINDING
AS
  SELECT TOP (100000) rowguid, SalesOrderID, n = NEWID() 
    FROM Sales.SalesOrderDetail ORDER BY NEWID();
GO

CREATE FUNCTION dbo.whatever(@SalesOrderID INT)
RETURNS UNIQUEIDENTIFIER
WITH SCHEMABINDING
AS
BEGIN
  RETURN 
  (
    SELECT TOP (1) rowguid FROM dbo.myview 
     WHERE SalesOrderID = @SalesOrderID ORDER BY n
  );
END
GO

Management Studioが行う(および行わない)内容

SSMSで次のクエリを実行します。

SET STATISTICS IO ON;

  SELECT TOP (5) SalesOrderID, dbo.whatever(SalesOrderID) 
    FROM Sales.SalesOrderHeader ORDER BY NEWID();

SET STATISTICS IO OFF;

あなたが計画を推定するときは、クエリのプランを取得し、単一機能のための計画(あなたが願うかもしれないとして、ない5):

Management Studioの推定計画

クエリが実際に実行されなかったため、I / Oデータはまったく取得されません。次に、実際の計画を生成します。結果グリッドで期待した5行を取得し、次の計画を立てます(これは、クエリテキストの一部として、およびスカラーオペレーターの一部として見つけることができるXMLを除いて、UDFについて目に見える言及はまったくありません)。

Management Studioの実際の計画

次のSTATISTICS IO出力(このテーブルから読み取る必要Sales.SalesOrderDetailがあることわかってても、についてはまったく言及していません):

テーブル 'SalesOrderHeader'。スキャンカウント1、論理読み取り57、物理読み取り0、先読み読み取り0、LOB論理読み取り0、LOB物理読み取り0、LOB先読み読み取り0。

プランエクスプローラーが教えてくれること

同じクエリの推定プランを生成すると、SSMSと同じことがわかります。ただし、少し直感的な方法で表示します。たとえば、外部クエリの推定プランは、関数の出力がクエリの出力とどのように組み合わされるかを示し、単一のプランダイアグラム内で、両方のテーブルからのI / Oがあることがすぐにわかります

プランエクスプローラーの推定プラン

また、関数の計画を単独示していますが、これは完全を期すためにのみ含めています。

Plan ExplorerでのUDFの推定計画

それでは、実際の計画を見てみましょう。これは、数千倍も有用です。ここでも欠点は、SQL Serverが表示することを決定した情報しか持っていないため、SQL Serverから提供されるグラフィカルな計画図しか公開できないことです。これは、有用な情報を表示しないことにした状況ではありません。提供されたプランXMLに基づいて、実際にそれについて何も知りません。この場合は、SSMSの場合と同様に、外部クエリのプランのみが表示され、関数がまったく呼び出されていないかのようになります

Plan Explorerの実際の計画

テーブルI / Oタブも、やはりの出力に依存してSTATISTICS IOおり、関数呼び出しで実行されるアクティビティも無視されます。

プランエクスプローラーの実際のプランのテーブルI / O

ただし、コールスタック全体が取得されます。「Pffft、いつコールスタックが必要になるか」という質問を時折耳にします。実際に1回の関数呼び出しごとに、費やされた時間、使用されたCPU、読み取り数(およびTVFの場合は生成された行数)を分析できます

UDF呼び出しを示すPlan Explorerの呼び出しスタック

残念ながら、I / Oがどのテーブルから行われているかを関連付けることはできません(これも、SQL Serverから情報が提供されないためです)。UDF名でラベル付けされていません。 (これは、関数呼び出し自体ではなく、アドホックステートメントとしてキャプチャされるためです)。しかし、Management Studioではできないことを見ることができるのは、UDFが飼っている犬です。まだいくつかのドットを結合する必要がありますが、ドットの数が少なく、ドット同士がより近くなっています。

プロファイラーについて

最後に、UIツールのスコープ外で実行するサーバー側のトレースを設定する場合を除いて、プロファイラーから離れることを強くお勧めします。プロファイラーを運用システムに対して使用すると、ほとんどの場合、これまでに解決されるよりも多くの問題が発生します。この情報を取得したい場合は、サーバー側のトレースまたは拡張イベントを使用して、非常に賢くフィルタリングしてください。プロファイラーがなくても、トレースはサーバーに影響を与える可能性があり、拡張イベントを通じてショープランを取得することも、世界で最も効率的な方法ではありません


ああ、プロ版のコールスタックは知りませんでした。それがまさに私が探していたものです。それが存在することを知っておくのは良いことです。現時点では、価格を正当化することはできないと思いますが、将来の状況に備えてそれを覚えておきます。SQL Serverが統計IOでUDFのI / O情報を提供しない理由はありますか?このような重要な情報を省略することは誤解を招く恐れがあります。
Gabe

3
@Gabe理由がわかりません。たぶん、コンサルタント業をより有利にするために?
アーロンバートランド

1
@gabeプランエクスプローラーは完全に無料です..呼び出された歩哨の1つで、すべてのプロ+究極のエディションの機能を備えています-すべて無料です。
Kin Shah
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.