データベース管理者は、常にSQLServerクエリのパフォーマンスを調整するように努めています。クエリパフォーマンスを調整する最初のステップは、クエリの実行プランを分析することです。条件によっては、SQLServerクエリオプティマイザーはさまざまな実行プランを作成できます。ここで、SQLServerクエリオプティマイザーに関するメモを追加します。 SQL Serverクエリオプティマイザーは、実行プランを分析し、クエリの最適な実行プランを決定するコストベースのオプティマイザーです。 SQL Serverクエリオプティマイザーの重要なキーワードは最適な実行プランであり、必ずしも最適な実行プランではありません。そのため、SQL Serverクエリオプティマイザーがすべてのクエリに最適な実行プランを見つけようとすると、余分な時間がかかり、SQLServerエンジンのパフォーマンスが低下します。 SQL Server 2016で、MicrosoftはCompareShowplanと呼ばれるSQLServerManagementStudioに新しい機能を追加しました。この機能により、2つの異なる実行計画を比較できます。同時に、このオプションをオフラインで使用できます。つまり、SQLServerインスタンスに接続する必要はありません。クエリを作成し、このクエリはTEST環境では良好に機能しますが、PROD(本番環境)では非常に不十分であると想像してください。この問題を処理するには、実行計画を比較する必要があります。この機能の前は、2つのSQL Server Management Studioを開いて実行プランを並べて表示していましたが、この方法は非常に不便でした。
2つの実行計画を比較するにはどうすればよいですか?
このデモンストレーションでは、AdventureWorksデータベースを使用して、カーディナリティ推定モデルのバージョンが異なる2つの実行プランを比較し、この違いをCompareShowplanで検出します。
まず、SQL Server Management Studioで新しいクエリウィンドウを開き、[実際の実行プランを含める]をクリックします。 次に、次のクエリを実行します。
SELECT soh.[SalesPersonID] ,p.[FirstName] + ' ' + COALESCE(p.[MiddleName], '') + ' ' + p.[LastName] AS [FullName] ,e.[JobTitle] ,st.[Name] AS [SalesTerritory] ,soh.[SubTotal] ,YEAR(DATEADD(m, 6, soh.[OrderDate])) AS [FiscalYear] FROM [Sales].[SalesPerson] sp INNER JOIN [Sales].[SalesOrderHeader] soh ON sp.[BusinessEntityID] = soh.[SalesPersonID] INNER JOIN [Sales].[SalesTerritory] st ON sp.[TerritoryID] = st.[TerritoryID] INNER JOIN [HumanResources].[Employee] e ON soh.[SalesPersonID] = e.[BusinessEntityID] INNER JOIN [Person].[Person] p ON p.[BusinessEntityID] = sp.[BusinessEntityID]
このステップでは、最初の実行プランを保存します。実行プランの任意の場所を右クリックし、名前を付けて実行プランを保存をクリックします。 実行プランをExecutionPlan_CE140.sqlplanとして保存します。
次に、SQL Server Management Studioで新しいクエリタブを開き、以下のクエリを実行します。このクエリでは、クエリの最後にFORCE_LEGACY_CARDINALITY_ESTIMATIONクエリヒントを追加して、古いカーディナリティ推定モデルバージョンを使用するように強制します。
カーディナリティ推定のタスク クエリが返す行数を予測することです。
SELECT soh.[SalesPersonID] ,p.[FirstName] + ' ' + COALESCE(p.[MiddleName], '') + ' ' + p.[LastName] AS [FullName] ,e.[JobTitle] ,st.[Name] AS [SalesTerritory] ,soh.[SubTotal] ,YEAR(DATEADD(m, 6, soh.[OrderDate])) AS [FiscalYear] FROM [Sales].[SalesPerson] sp INNER JOIN [Sales].[SalesOrderHeader] soh ON sp.[BusinessEntityID] = soh.[SalesPersonID] INNER JOIN [Sales].[SalesTerritory] st ON sp.[TerritoryID] = st.[TerritoryID] INNER JOIN [HumanResources].[Employee] e ON soh.[SalesPersonID] = e.[BusinessEntityID] INNER JOIN [Person].[Person] p ON p.[BusinessEntityID] = sp.[BusinessEntityID] OPTION (USE HINT ('FORCE_LEGACY_CARDINALITY_ESTIMATION'));
ショープランの比較をクリックします そして、ExecutionPlan_CE140.sqlplanとして保存された以前の実行プランを選択します。
次の画像は、SQL Server実行比較計画の最初の画面を示しており、ピンク色で強調表示された領域が同様の操作を定義しています。
実行プラン画面の下または上のいずれかの演算子をクリックすると、SQL ServerManagementStudioは他の同様の演算子を強調表示します。パネルの右側には、プロパティとプロパティの比較の詳細が表示されます。
このステップでは、ShowPlan Analysisオプションを変更し、一致しない演算子を強調表示します。画面の下部に、ショープラン分析が表示されます。 パネル。 同様の操作を強調表示をクリアすると 類似のセグメントに一致しない演算子を強調表示するを選択します SQL Server Management Studioは、一致しない演算子を強調表示します。その後、演算子の選択をクリックします パネルの実行計画の下と上にあります。 SQL Server Management Studioは、選択した演算子のプロパティを比較し、不等式の符号を同一でない値に配置します。
この画面をさらに詳しく分析すると、まずはカーディナリティ推定モデルバージョンです。 違い。最初のクエリバージョンは70で、2番目のクエリバージョンは140です。この違いは、推定行数に影響します。 。 推定行数が異なる主な理由 カーディナリティ推定の異なるバージョンです。したがって、カーディナリティ推定バージョンは、クエリ推定メトリックに直接影響します。このクエリの比較では、推定行数が実際の行数に近いため、カーディナリティ推定バージョンが140のクエリの方がパフォーマンスが高いと結論付けることができます。 。このケースは、以下の表から明らかにすることができます。
[テーブルID=50 /]
同じ画面に実行計画を並べて表示したい場合は、スプリッターの向きを切り替えるをクリックします。 。
次に、別のデモンストレーションを行います。以下のクエリを見て、インデックス作成の前後の実行プランを比較します。
以下のクエリ実行プランを見るときは、非クラスター化インデックスを作成することをお勧めします。
SELECT [CarrierTrackingNumber] FROM [Sales].[SalesOrderDetail] WHERE [SalesOrderDetailID]=12
推奨されるインデックスを適用し、同じクエリを再実行します。
CREATE NONCLUSTERED INDEX Index_NC ON [Sales].[SalesOrderDetail] ([SalesOrderDetailID]) GO SELECT [CarrierTrackingNumber] FROM [Sales].[SalesOrderDetail] WHERE [SalesOrderDetailID]=12
この最後のステップでは、実行計画を比較します。
上の画像では、実行計画に関するいくつかの情報を取得できます。ただし、主な違いは論理演算です。 分野。その1つがインデックスシークです。 もう1つはインデックススキャンです この操作の違いにより、推定値と実際のメトリック値が異なります。最後に、インデックスシーク演算子はインデックススキャン演算子よりもパフォーマンスが優れています。
結論
記事で述べたように、Showplanの比較機能は、データベース開発者または管理者にいくつかの利点を提供します。これらのいくつかは次のように数えることができます:
- 2つの実行計画の違いを簡単に比較できます。
- さまざまなSQLServerバージョンでのクエリパフォーマンスの問題を簡単に検出できます。
- さまざまな環境でクエリのパフォーマンスの問題を簡単に検出できます。
- インデックス作成の前後の実行プランの変更を明確にするだけです。
参照
- カーディナリティ推定(SQL Server)
- クエリ処理アーキテクチャガイド