明らかな免責事項:私はSQL Sentryで働いています。
私たちが抱えている最大の問題は次のとおりです。
- @JNKが言うように、SQL ServerはUDFの使用を難読化し、とにかくひどいことをします(常に1行を推定するように)。SSMSで実際のプランを生成しても、その使用法はまったくわかりません。SQL Serverが提供するプランに関する情報しか提供できないため、同じ制限を受けます。
- 実際の計画を生成するとき、ランタイムメトリックのさまざまなソースに依存しています。残念ながら、プランの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):
クエリが実際に実行されなかったため、I / Oデータはまったく取得されません。次に、実際の計画を生成します。結果グリッドで期待した5行を取得し、次の計画を立てます(これは、クエリテキストの一部として、およびスカラーオペレーターの一部として見つけることができるXMLを除いて、UDFについて目に見える言及はまったくありません)。
次のSTATISTICS IO
出力(このテーブルから読み取る必要Sales.SalesOrderDetail
があることがわかっていても、についてはまったく言及していません):
テーブル 'SalesOrderHeader'。スキャンカウント1、論理読み取り57、物理読み取り0、先読み読み取り0、LOB論理読み取り0、LOB物理読み取り0、LOB先読み読み取り0。
プランエクスプローラーが教えてくれること
同じクエリの推定プランを生成すると、SSMSと同じことがわかります。ただし、少し直感的な方法で表示します。たとえば、外部クエリの推定プランは、関数の出力がクエリの出力とどのように組み合わされるかを示し、単一のプランダイアグラム内で、両方のテーブルからのI / Oがあることがすぐにわかります。
また、関数の計画を単独で示していますが、これは完全を期すためにのみ含めています。
それでは、実際の計画を見てみましょう。これは、数千倍も有用です。ここでも欠点は、SQL Serverが表示することを決定した情報しか持っていないため、SQL Serverから提供されるグラフィカルな計画図しか公開できないことです。これは、有用な情報を表示しないことにした状況ではありません。提供されたプランXMLに基づいて、実際にそれについて何も知りません。この場合は、SSMSの場合と同様に、外部クエリのプランのみが表示され、関数がまったく呼び出されていないかのようになります。
テーブルI / Oタブも、やはりの出力に依存してSTATISTICS IO
おり、関数呼び出しで実行されるアクティビティも無視されます。
ただし、コールスタック全体が取得されます。「Pffft、いつコールスタックが必要になるか」という質問を時折耳にします。実際に、1回の関数呼び出しごとに、費やされた時間、使用されたCPU、読み取り数(およびTVFの場合は生成された行数)を分析できます。
残念ながら、I / Oがどのテーブルから行われているかを関連付けることはできません(これも、SQL Serverから情報が提供されないためです)。UDF名でラベル付けされていません。 (これは、関数呼び出し自体ではなく、アドホックステートメントとしてキャプチャされるためです)。しかし、Management Studioではできないことを見ることができるのは、UDFが飼っている犬です。まだいくつかのドットを結合する必要がありますが、ドットの数が少なく、ドット同士がより近くなっています。
プロファイラーについて
最後に、UIツールのスコープ外で実行するサーバー側のトレースを設定する場合を除いて、プロファイラーから離れることを強くお勧めします。プロファイラーを運用システムに対して使用すると、ほとんどの場合、これまでに解決されるよりも多くの問題が発生します。この情報を取得したい場合は、サーバー側のトレースまたは拡張イベントを使用して、非常に賢くフィルタリングしてください。プロファイラーがなくても、トレースはサーバーに影響を与える可能性があり、拡張イベントを通じてショープランを取得することも、世界で最も効率的な方法ではありません。