実行計画と統計IO注文


20

SQL Serverのグラフィカルな実行計画は、右から左、上から下に読みます。によって生成された出力に意味のある順序はありSET STATISTICS IO ONますか?

次のクエリ:

SET STATISTICS IO ON;

SELECT  *
FROM    Sales.SalesOrderHeader AS soh
        JOIN Sales.SalesOrderDetail AS sod ON soh.SalesOrderID = sod.SalesOrderID
        JOIN Production.Product AS p ON sod.ProductID = p.ProductID;

この計画を生成します。

グラフィカルな実行計画

そして、このSTATISTICS IO出力:

Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'SalesOrderDetail'. Scan count 1, logical reads 1246, physical reads 3, read-ahead reads 1277, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'SalesOrderHeader'. Scan count 1, logical reads 689, physical reads 1, read-ahead reads 685, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Product'. Scan count 1, logical reads 15, physical reads 1, read-ahead reads 14, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

繰り返しますが、何が得られるのでしょうか?STATISTICS IO出力する意味のある順序はありますか、または任意の順序が使用されていますか?

回答:


9

さまざまなクエリを最初に試したところ、パターンはまったくありませんでしたが、細心の注意を払うと、シリアルプランで予測できるように見えます。私は@AustinZellnerが言及しているKB314648になりました:

各SQL Server接続には、接続固有の状態情報を保持するプロセス状態構造(PSS)が関連付けられています。sysprocessesシステムテーブルの各一意のサーバープロセスID(SPID)は異なるPSSを表し、sysprocesses仮想テーブルの情報はこのステータス情報の「ビュー」です。

そしてあなたの質問に関連するセクション:

接続に対してSTATISTICS IOが有効になっている場合、SQL Serverはクエリ実行中に配列を割り当て、テーブルごとにIO情報を追跡します。SQL Serverはクエリを処理するときに、この論理IOリクエストが物理IOになったかどうかとともに、ページの各論理リクエストをこの配列の適切なテーブルのエントリに記録します。SQL Serverは、クエリの最後にエラーメッセージ3615で情報を返します。

観察された動作は、IOが生成される順序で配列にエントリが作成されることを示しています。これは、基本的に物理演算子でのGetNext()の結果です。統計出力の最後のエントリは、IOが記録された最初のテーブルであり、最初のエントリは最後のテーブルです。どの並列タスクが最初にスケジュールされるかについての保証がないため、並列計画の順序は予測できない(または、そうではない)と推測します。


5

計画ではデータ読み取りアクセスの逆の順序のように見えます。プランは最初にProductテーブルから読み取り、ハッシュテーブル(作業テーブル)を作成します。SalesOrderHeaderから読み取り、それらをマージ結合演算子と組み合わせてSalesOrderDetailを作成するよりも。その後、ワークテーブルが最後から読み取られ、元の製品行とマージ結合の行がハッシュ一致します。これは、統計出力にリストされる順序とまったく逆の順序です。

ただし、これを指定するドキュメントについては知りません。テーブルアクセスが発生した順序を確認したい場合は、実行計画を読んでください。


この場合、逆の順序で処理されますが、他の場合は異なります。一般に公開されていないエンジンの詳細な知識がなければ、発見できる順序はないと思います。
ジェレマイアペシュカ

別の順序での例はありますか?
セバスチャンマイネ

SELECT * FROM Sales.SalesOrderHeader AS soh JOIN Sales.SalesOrderDetail AS sod ON soh.SalesOrderID = sod.SalesOrderID LEFT JOIN Sales.SalesPerson AS sp ON soh.SalesPersonID = sp.BusinessEntityID LEFT JOIN Person.Person AS p2 ON sp.BusinessEntityID = p2 .BusinessEntityID JOIN Production.Product AS p ON sod.ProductID = p.ProductID;
ジェレマイアペシュカ

並列性が関与しない限り、私の観察は真実です。TOP(100)、TOP(1000)、およびTOP(10000)でクエリを実行して、シリアルプランを表示できます。ただし、TOP(100000)を使用する場合、またはTOPを使用しない場合、2つの異なる並行プランが得られ、すべてのベットがオフになっているように見えます。
セバスチャンマイネ

3

私は、管理よりもプログラミングをしたときから、常に秩序があると思っていました。いくつかの実行計画を実行し、自分の信念を再確認しました。

ここに私が見るものがあります:

マルチステップクエリ(ストアドプロシージャの多くなど)では、順序はクエリが実行される物理的な順序を反映しています。

特定のクエリでは、右から開始して左に向かって統計情報を報告することにより、統計IOが実行計画を反映しているように見えます

おそらく、これは他の何よりも観察の詳細です。


2
これに何かあるかもしれません。表の順序をSELECT COUNT(*) FROM HumanResources.EmployeeDepartmentHistory UNION ALL SELECT COUNT(*) FROM HumanResources.Employee UNION ALL SELECT COUNT(*) FROM HumanResources.Department逆にするとIO出力も逆になりますが、質問の例で作業表が最初に報告される理由は説明されていません。
マーティンスミス

@MartinSmithはい、ワークテーブルは私の限られた観点からはワイルドカードです。
RLF

0

したがって、統計の結果は実行時に実際に何が起こっているのかをより多くの洞察を与えると考えていますクエリが実行されていること。統計の戻り値でのテーブルの位置は、プロファイラで考慮されている要因以外の要因の影響を受けます。

洞察といくつかの例を与えるKB記事はここにあります:http : //support.microsoft.com/kb/314648


1
質問はSTATISTICS IO一般的な出力に関するものではありません。純粋に、さまざまなテーブルの読み取りが報告される順序についてです。あなたのリンクにはこれについて何も見当たりません。
マーティンスミス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.