私はこのようなクエリを持っています:
select dbo.fn_complexFunction(t.id)
from mytable t
SQL Sentry Plan Explorerで、クエリプランにUDFを含めるには、SQL SentryでGet Estimated Planを実行する必要があることに気付きました。
「実際のプランを取得」を実行すると、論理読み取りやその他のメトリックにUDFで発生する操作が含まれているように見えません。このような場合、プロファイラーを使用する唯一の回避策はありますか?
明らかな免責事項:私は SQL Sentry 。のために働きます
私たちが抱えている最大の問題は次のとおりです。
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;
プランを見積もるとき、あなたは クエリのプランを取得しますand a single関数のプラン (ご希望のように5ではありません) :
クエリが実際に実行されなかったため、I/Oデータをまったく取得しません。次に、実際の計画を生成します。結果グリッドで期待した5行を取得します 次の計画 (これは、クエリテキストの一部として、および一部として見つけることができるXMLを除いて、UDFについて目に見える言及をまったく行いません)スカラー演算子の)):
そして、次のSTATISTICS IO
出力(これはSales.SalesOrderDetail
についてまったく言及していませんが、そのテーブルから読み取るにはhadです):
テーブル '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、いつコールスタックが必要になるのか」という質問をときどき耳にしました。実際に 費やした時間、使用されたCPU、および読み取りの数(およびTVFの場合は生成された行の数)をすべての1つ関数呼び出し に分解できます。
残念ながら、I/Oの送信元のテーブルに関連付けることはできません(ここでも、SQL Serverはその情報を提供しないため)、UDF名でラベル付けされていません(これは、関数呼び出し自体ではなく、アドホックステートメントとしてキャプチャされるためです)。しかし、Management Studioではできないことを見ることができるのは、UDFがどんな犬なのかです。まだいくつかのドットを結合する必要がありますが、ドットの数は少なく、それらはより近くにあります。
プロファイラについて
最後に、UIツールのスコープ外で実行するサーバー側のトレースを設定する場合を除いて、Profilerから離れることを強くお勧めします。 プロファイラーを本番システムに対して使用すると、ほぼ確実に、これまでに解決されるよりも多くの問題が発生します 。この情報を取得したい場合は、サーバー側のトレースまたは拡張イベントを使用し、非常に賢くフィルタリングしてください。プロファイラーがなくても、トレースがサーバーに影響を与える可能性があります 拡張イベントを通じてショープランを取得することも、世界で最も効率的な方法ではありません 。