SQL Server

SQL Server の CPU パフォーマンスを最適化する

Zach Nichter

 

概要:

  • データベースのパフォーマンスに関する問題のトラブルシューティングを行う
  • ハードウェアに原因があるかどうかを確認する
  • パフォーマンス モニタを使用してデータベースのボトルネックを追跡する
  • クエリのパフォーマンスを評価する

データベース システムのパフォーマンスに関する問題のトラブルシューティングは、手に負えないほど厄介な作業になる場合があります。調査が必要な箇所を知っていることも重要ですが、特定の要求に対してシステムがなぜそのように動作するのかを知っていることの方が重要です。データベース サーバーの CPU 使用率に影響する要因は

さまざまです。たとえば、SQL ステートメントのコンパイルと再コンパイル、インデックスの欠落、マルチスレッド操作、ディスクのボトルネック、メモリのボトルネック、定期的なメンテナンス、ETL (抽出、変換、読み込み) 処理などがあります。CPU が使用されること自体は、悪いことではありません。CPU があるのは、作業を行うためですから。CPU 使用率を正常に保つには、必要な処理に CPU が使用され、最適化が不十分なコードや動作の遅いハードウェアのために無駄なサイクルが発生しないようにすることが重要です。

問題を特定する 2 つの作業

大きく分けて、CPU のパフォーマンスに関する問題を特定するために行う作業は 2 つあります。1 つ目は、システムのハードウェアのパフォーマンスを確認することです。この作業を行って、調査が必要な箇所を特定しておくと、サーバーのクエリ効率を確認するという 2 つ目の作業を行う際に役立ちます。通常、SQL Server™ のパフォーマンスに関する問題を特定する場合は、2 つ目の作業のほうが効果的です。ただし、クエリのパフォーマンスに関する問題の原因となっている箇所を正確に把握していない場合は、必ず最初にシステムのパフォーマンスを評価してください。通常、最終的には、両方の作業を行うことになります。2 つの作業について説明する前に、まず基盤となる技術について説明します。

基盤技術を理解する

ハイパースレッディング

ハイパースレッディングについては、これが SQL Server に影響するしくみを考えると、少し詳しく説明しておいた方がよいでしょう。ハイパースレッディングでは、1 つの物理プロセッサにつき 2 つの論理プロセッサが OS に提供されます。基本的には、物理プロセッサの時間をリースすることにより、各プロセッサがより有効に使用されるようにするための技術です。ハイパースレッディングのしくみの詳細については、Intel の Web サイト (intel.com/technology/platform-technology/hyper-threading/index.htm) を参照してください。

SQL Server システム上では、実際には DBMS が OS に対して非常に効率的なキュー処理とスレッディングを行っているため、既に CPU 使用率が高いシステムでハイパースレッディングを有効にしても、物理 CPU への負荷が増すだけです。SQL Server が複数のスケジューラを操作するために複数の要求をキューに入れた場合、1 つの物理プロセッサが 2 つの論理プロセッサとして使用されている場合でも、OS は要求された処理を実行するために、その物理プロセッサのスレッド間でコンテキストを切り替える必要があります。Context Switches/sec が 1 物理プロセッサあたり 5,000 を超えている場合は、システムでハイパースレッディングを無効にした後、再度パフォーマンスをテストすることを強くお勧めします。

まれに、SQL Server システム上で高い CPU 使用率を示すアプリケーションがある場合、ハイパースレッディングが効果的に作用することがあります。SQL Server システムで、ハイパースレッディングを有効にした状態と無効にした状態の両方でアプリケーションをテストしてから、運用システムに変更を実装するようにしてください。

コンピュータの RAM は接続型のストレージ デバイスよりも処理性能が優れていますが、ハイエンドのデュアルコア プロセッサは、その RAM よりも格段に高速です。高性能の CPU は、現在のトップエンドの DDR2 メモリの約 6 倍、およびトップエンドの DDR3 メモリの約 2 倍のスループットを処理できます。通常、メモリのスループットは、最速のファイバ チャネル ドライブの 10 倍以上です。また、ハード ディスクは、限られた数の IOPS (1 秒あたりの入出力操作) しか実行できません。この数は、ドライブが実行できる 1 秒あたりのシーク数によってのみ制限されます。ただし、1 つのストレージ ドライブのみによって、エンタープライズ データベース システムのストレージ要件が満たされることはあまりありません。現在の一般的な構成では、エンタープライズ データベース サーバーにストレージ エリア ネットワーク (SAN) を使用するか、ディスク I/O プロセッサの問題を解消または最小限に抑えることができる大規模な RAID グループを使用しています。最も重要なことは、どのような構成であっても、ディスクとメモリのボトルネックが、プロセッサのパフォーマンスに影響する可能性があるということです。

I/O 速度の違いにより、ディスクからデータを取得する場合は、メモリからデータを取得する場合よりもかなりコストがかかります。SQL Server のデータ ページは 8 KB です。SQL Server のエクステントは、この 8 KB のページを 8 ページ使用して構成されるため、64 KB になります。SQL Server がディスク上の特定のデータ ページを要求するとき、取得されるデータ ページだけでなく、そのデータ ページがあるエクステント全体が取得されるため、このことを理解しておく必要があります。実際には、SQL Server にとってこれがコスト効率の向上につながる理由がありますが、ここでは詳細は省きます。バッファ プールから既にキャッシュされているデータ ページを取得する際にかかる時間は、最速で 0.5 ミリ秒未満ですが、ディスクから 1 つのエクステントを取得する場合は、最適な環境で 2 ~ 4 ミリ秒です。通常、パフォーマンスがよく、正常なディスク サブシステムでは、読み取りに 4 ~ 10 ミリ秒かかると思われます。メモリからデータ ページを取得する場合は、通常、ディスクからデータ ページを取得するよりも 4 ~ 20 倍高速です。

SQL Server はデータ ページを要求するとき、ディスク サブシステム上のデータ ページを検索する前に、まずメモリ内のバッファ キャッシュを確認します。データ ページがバッファ プール内で見つかった場合、プロセッサはこのデータを取得し、要求された作業を行います。これは、ソフト ページ フォールトと呼ばれます。要求の一環として取得されるデータを使用するには、このデータがバッファ キャッシュに読み込まれている必要があるため、ソフト ページ フォールトは SQL Server にとって理想的な処理です。バッファ キャッシュにないデータ ページは、サーバーのディスク サブシステムから取得する必要があります。OS がデータ ページをディスクから取得する必要がある場合、その動作はハード ページ フォールトと呼ばれます。

メモリ パフォーマンス、ディスク パフォーマンス、および CPU パフォーマンスの相関関係を知るには、共通の指標から考えると全体図を把握しやすくなります。その指標とはスループットです。科学用語を使用せずに説明すると、スループットは、限られた大きさのパイプにどれだけ多くのデータを詰め込むことができるかを示す数値です。

作業 1: システムのパフォーマンス

サーバーの CPU がボトルネックになっているかどうかを確認する方法はごくわずかしかなく、高い CPU 使用率を引き起こす可能性がある要因もそれほど多くありません。これらの問題の中には、パフォーマンス モニタまたは同様のシステム監視ツールを使用して追跡できるものや、SQL Server Profiler などのツールを使用して追跡できるものがあります。別の方法としては、クエリ アナライザや SQL Server Management Studio (SSMS) から SQL コマンドを使用します。

システムのパフォーマンスを評価する際の私の方針は、"最初は全体を見て、後から範囲を絞り込む" というものです。当然ながら、問題のある領域を特定しなければ、それらの問題に取り組むことはできません。パフォーマンス モニタなどのツールを使用して全体的な CPU 使用率を評価したら、そのツールを使用して、非常に単純かつ理解しやすいいくつかのパフォーマンス カウンタを確認します。

パフォーマンス モニタを使用する場合、最も頻繁に参照するパフォーマンス カウンタの 1 つは % Processor Time です。これは、[カウンタの追加] ウィンドウを開くと強調表示されているカウンタです。% Processor Time は、プロセッサが処理を実行してビジー状態になっている時間を示しています。通常、ピーク稼働時間のほとんどの間、この値が 80% 以上を示す場合、プロセッサの使用率は高いと見なされます。ピーク稼働時間のサーバーの使用率が 80% 未満の場合でも、ときどき使用率が 100% に急上昇することがありますが、これは一般的な動作であり、異常が発生しているわけではありません。

確認が必要なもう 1 つのカウンタは Processor Queue Length です。これは、パフォーマンス モニタの System パフォーマンス オブジェクトのカウンタです。Processor Queue Length は、CPU 上で処理を実行するために待機しているスレッドの数を示しています。SQL Server では、データベース エンジンのスケジューラによって処理を管理し、SQL Server 自体の要求をキューに入れたり処理したりします。SQL Server は SQL Server 自体の処理を管理するため、各論理プロセッサにつき 1 つの CPU スレッドしか使用しません。つまり、SQL Server 専用のシステムでは、処理を実行するためにプロセッサのキューで待機しているスレッドの数を最小限に抑える必要があります。通常、SQL Server 専用のシステムでは物理プロセッサ数の 5 倍未満の数である必要がありますが、私は 2 倍でも問題であると考えます。DBMS が他のアプリケーションとシステムを共有しているサーバー上では、% Processor Time および Context Switches/sec パフォーマンス カウンタと併せてこのカウンタを確認し (コンテキスト スイッチについては後述します)、他のアプリケーションか DBMS を別のサーバーに移動する必要があるかどうかを判断するとよいでしょう。

CPU 使用率が高いだけでなく、プロセッサのキューが使用されている場合は、SQL Server: SQL Statistics パフォーマンス オブジェクトの Compilations/sec と Re-Compilations/sec カウンタも確認します(図 1 参照)。クエリ プランのコンパイルと再コンパイルを行うと、システムの CPU 使用率が増加します。Re-Compilations の値はゼロに近いはずですが、システム内の傾向を観察し、サーバーの通常の動作とコンパイル数を確認してください。再コンパイルは常に回避できるとは限りませんが、クエリとストアド プロシージャを最適化することで、再コンパイルを最小限に抑えたり、クエリ プランを再利用したりできます。SQL Server: SQL Statistics パフォーマンス オブジェクトの Batch Requests/sec を使用して、コンパイルと再コンパイルの値を、実際にシステムが受け取る SQL ステートメントの数と比較します。1 秒あたりにシステムが受け取るバッチ要求の中に、コンパイルと再コンパイルが高い割合で含まれる場合、この領域を見直す必要があります。場合によっては、開発したコードがどのようにまたはなぜこのようなシステム リソースの問題に関与しているかを SQL 開発者が理解していないことがあります。この記事では後ほど、可能な限りこのような事態に陥らないようにするための参考情報を提供します。

図 1 監視するカウンタの選択

図 1** 監視するカウンタの選択 **(画像を拡大するには、ここをクリックします)

パフォーマンス モニタで Context Switches/sec というパフォーマンス カウンタを確認します (図 2 を参照)。このカウンタは、他の待機中のスレッドの処理を行うために、(SQL のスケジューラではなく) OS のスケジューラのスレッドが切り替えられた回数を示します。コンテキストの切り替えは、IIS や他のベンダのアプリケーション サーバー コンポーネントと共有されているデータベース システムでより頻繁に発生する傾向があります。Context Switches/sec のしきい値は、サーバーのプロセッサ数の 5,000 倍を目安にします。この値は、ハイパースレッディングが有効になっていて、中程度から高い CPU 使用率を示すシステムでは高くなります。CPU 使用率とコンテキストの切り替え数の両方が定期的にしきい値を超える場合は、CPU がボトルネックになっています。この現象が定期的に見られ、使用しているシステムが古い場合は、CPU を追加購入するか、より高速な CPU を購入することを検討する必要があるでしょう。詳細については、補足記事「ハイパースレッディング」を参照してください。

Figure 2 監視が必要なパフォーマンス カウンタ

パフォーマンス カウンタ カウンタ オブジェクト しきい値 説明
% Processor Time Processor 80% 以上 メモリ不足、クエリ プランの再利用率が低いこと、クエリが最適化されていないことなどが、原因として考えられます。
Context Switches/sec System プロセッサ数の 5,000 倍以上 サーバー上に他のアプリケーションが展開されていること、SQL Server の複数のインスタンスが同じサーバー上で実行されていること、ハイパースレッディングが有効になっていることなどが、原因として考えられます。
Processor Queue Length System プロセッサ数の 5 倍以上 サーバー上に他のアプリケーションが展開されていること、コンパイルや再コンパイルが頻繁に発生すること、SQL Server の複数のインスタンスが同じサーバー上で実行されていることなどが、原因として考えられます。
Compilations/sec SQLServer:SQL Statistics 傾向 Batch Requests/sec と比較します。
Re-Compilations/sec SQLServer:SQL Statistics 傾向 Batch Requests/sec と比較します。
Batch Request/sec SQLServer:SQL Statistics 傾向 Compilations/sec および Re-Compilations/sec と比較します。
Page Life Expectancy SQLServer:Buffer Manager 300 以上 メモリ不足の可能性があります。
Lazy Writes/sec SQLServer:Buffer Manager 傾向 データ キャッシュがフラッシュされる頻度が高いか、メモリ不足の可能性があります。
Checkpoints/sec SQLServer:Buffer Manager 傾向 PLE および Lazy Writes/sec と比較して、チェックポイントの影響を評価します。
Cache Hit Ratio: SQL Plans SQLServer:Plan Cache 70% 以上 プランの再利用率が低いことを示しています。
Buffer Cache Hit Ratio SQLServer:Buffer Manager 97% 以上 メモリ不足の可能性があります。
       

SQL Server レイジー ライタ (SQL Server 2000 での名称) またはリソース モニタ (SQL Server 2005 での名称) は、CPU 使用率が高いときに監視すべき領域の 1 つです。バッファおよびプロシージャのキャッシュをフラッシュすると、リソース モニタという名前のリソース スレッドにより CPU 時間が増大する可能性があります。リソース モニタは、どのページを保持し、どのページをバッファ プールからディスクにフラッシュする必要があるかを決定する SQL Server プロセスです。バッファおよびプロシージャ キャッシュ内の各ページには、もともとページがキャッシュに読み込まれたときに使用されるリソースを表すコストが割り当てられています。このコストの値は、リソース モニタがページをスキャンするたびに減少します。ある要求でキャッシュ領域が必要になった場合、各ページに関連付けられているコストを基にメモリからページがフラッシュされます。コストが最も低いページからディスクにフラッシュされます。リソース モニタの動作状況は、パフォーマンス モニタで SQL Server: Buffer Manager オブジェクトの Lazy Writes/sec パフォーマンス カウンタを参照することで追跡できます。この値の傾向を追跡して、使用中のシステムでの標準的なしきい値を特定してください。通常、このカウンタは、メモリが不足しているかどうかを確認するために、Page Life Expectancy および Checkpoints/sec カウンタと併せて参照されます。

Page Life Expectancy (PLE) カウンタは、メモリが不足しているかどうかを確認する際に役立ちます。PLE カウンタは、あるデータ ページがバッファ キャッシュに保持されている時間を示します。このカウンタのしきい値として業界で認められている値は 300 秒です。長時間の平均が 300 秒未満である場合は、データ ページがメモリからフラッシュされる頻度が高すぎます。この場合、リソース モニタの負荷が高くなり、その結果、プロセッサの負荷も高くなります。PLE カウンタは、Checkpoints Pages/sec カウンタと併せて評価する必要があります。システムのチェックポイントが発生すると、バッファ キャッシュ内のダーティ データ ページがディスクにフラッシュされ、PLE 値が減少します。リソース モニタ プロセスは、これらのページをディスクにフラッシュするメカニズムであるため、システムのチェックポイントが発生した場合は Lazy Writes/sec の値も増加すると考えてください。チェックポイントの完了直後に PLE 値が増加した場合は、一時的な現象であるため、無視して問題ありません。一方、定期的に PLE の値がしきい値よりも低くなる場合は、メモリを追加することで、問題が緩和されると同時に、一部のリソースが再び CPU に解放される可能性があります。これらのカウンタはすべて、SQL Server: Buffer Manager パフォーマンス オブジェクトのカウンタです。

作業 2: クエリのパフォーマンス

SP によるトレース

SQL Server アプリケーションをトレースする場合は、トレース用のストアド プロシージャについて知っておくとよいでしょう。トレース用の GUI インターフェイス (SQL Server Profiler) を使用すると、システムの負荷が 15 ~ 25% 増加する可能性があります。トレースにストアド プロシージャを使用すると、この負荷を約半分に抑えることができます。

システムのいずれかの部分がボトルネックになっていることがわかっていて、現在使用している SQL ステートメントの中で、サーバーで発生している問題の原因になっているものを特定する必要がある場合は、次のようなクエリを実行します。このクエリを実行すると、各ステートメントとこれらが現在使用しているリソースのほか、パフォーマンスを向上させるために見直す必要があるステートメントを確認できます。SQL トレースの詳細については、msdn2.microsoft.com/ms191006.aspx を参照してください。

SELECT 
    substring(text,qs.statement_start_offset/2
        ,(CASE    
            WHEN qs.statement_end_offset = -1 THEN len(convert(nvarchar(max), text)) * 2 
            ELSE qs.statement_end_offset 
        END - qs.statement_start_offset)/2) 
    ,qs.plan_generation_num as recompiles
    ,qs.execution_count as execution_count
    ,qs.total_elapsed_time - qs.total_worker_time as total_wait_time
    ,qs.total_worker_time as cpu_time
    ,qs.total_logical_reads as reads
    ,qs.total_logical_writes as writes
FROM sys.dm_exec_query_stats qs
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st
    LEFT JOIN sys.dm_exec_requests r 
        ON qs.sql_handle = r.sql_handle
ORDER BY 3 DESC

新しいクエリが SQL Server に発行されると、クエリ プランが評価、最適化、およびコンパイルされ、プロシージャ キャッシュに格納されます。クエリがサーバーに発行されるたびに、プロシージャ キャッシュが確認され、要求に合ったクエリ プランが検索されます。適合するものが見つからなかった場合、SQL Server はこの要求用に新しいプランを作成しますが、この操作によって負荷が上昇する可能性があります。

CPU のパフォーマンスを向上させるために T-SQL を最適化する際の考慮事項を次に示します。

  • クエリ プランの再利用
  • コンパイルおよび再コンパイル回数の削減
  • 並べ替え操作
  • 適切でない結合
  • インデックスの欠落
  • テーブルとインデックスのスキャン
  • SELECT 句と WHERE 句での関数の使用
  • マルチスレッド操作

では、先ほどと同じように、少し全体的な視点に立って考えてみましょう。通常、SQL Server はデータをメモリとディスクの両方から取得します。また、1 つのデータ ページのみが操作されることはあまりありません。多くの場合、アプリケーションの複数の部分で、レコードの操作、複数の小さなクエリの実行、テーブルの結合などが行われた結果、関連データの総合的な表示が提供されます。OLAP 環境では、アプリケーションが数百万行を 1 つまたは 2 つのテーブルから取得し、それらのデータを統合、ロールアップ、および要約して地域別売上レポートを作成している場合があります。このような状況では、データがメモリにある場合はミリ秒単位でデータが返されますが、同じデータを RAM ではなくディスクから取得する場合、このミリ秒が分単位に変わる可能性があります。

最初の例としては、大量のトランザクションがあり、プランの再利用率がアプリケーションによって異なる状況が挙げられます。クエリ プランの再利用率が低い場合、SQL ステートメントのコンパイル回数が増加し、その結果 CPU の処理量が大幅に増加します。2 番目の例としては、システム リソースの使用率が高いことが原因で、システムの CPU の負荷が高くなる状況が挙げられます。大量の新しいデータ ページ用の領域を確保する場合、既存のデータを頻繁にバッファ キャッシュからフラッシュする必要があるため、このような状況が発生します。

たとえば、トランザクション数の多いシステムがあるとします。このシステムでは、発送用のダンボールに関する情報を取得する次のような SQL ステートメントが、15 分間に 2,000 回実行されます。クエリ プランが再利用されない場合、1 ステートメントあたりの実行時間は 450 ミリ秒と仮定できます。最初の実行後、同じクエリ プランが再利用された場合、2 回目以降のクエリはおそらく約 2 ミリ秒で実行されるため、全体の実行時間は約 5 秒に短縮されます。

USE SHIPPING_DIST01;
SELECT 
    Container_ID
    ,Carton_ID
    ,Product_ID
    ,ProductCount
    ,ModifiedDate
FROM Container.Carton
WHERE Carton_ID = 982350144;

トランザクションが多いシステムのパフォーマンスを最適化する場合、クエリ プランを再利用することが重要になります。これは多くの場合、クエリやストアド プロシージャをパラメータ化することで実現されます。クエリ プランの再利用については、次の資料を参照してください。

  • SQL Server 2005 のバッチのコンパイル、再コンパイル、およびプランのキャッシュに関する問題 (microsoft.com/technet/prodtechnol/sql/2005/recomp.mspx)
  • SQL Server のストアド プロシージャを最適化して再コンパイルを回避する (sql-server-performance.com/rd_optimizing_sp_recompiles.asp)
  • SQL Server 2000 におけるクエリの再コンパイル (msdn2.microsoft.com/aa902682.aspx)

SQL Server 2005 の動的管理ビュー (DMV) を使用すると、さまざまな情報を確認できます。CPU 使用率が高い場合、いくつかの DMV を使用して、CPU が適切に使用されているかどうかを判断できます。

1 つ目の DMV は sys.dm_os_wait_stats です。DBA は、この DMV を使用して、SQL Server が使用する各リソースの種類や関数を確認できます。また、この DMV では、使用される各リソースをシステムが待機する時間も計測されます。この DMV のカウンタは累積的です。つまり、システムの他の領域に影響している可能性があるリソースを特定するには、まずデータに目立った問題がないことを確認した後、DBCC SQLPERF('sys.dm_os_wait_stats', CLEAR) コマンドを実行して、カウンタのすべてのデータをリセットする必要があります。sys.dm_os_wait_stats DMV は、SQL Server 2000 でデータベースの整合性を確認するために使用するコマンドである DBCC SQLPERF(WAITSTATS) に相当します。待機の種類については、SQL Server Books Online (msdn2.microsoft.com/ ms179984.aspx) を参照してください。

すべての処理が最適な状態で実行されていても、通常はシステムで待機が発生することを認識しておいてください。必要なのは、それらの待機が CPU のボトルネックの影響を受けているかどうかを判断することです。シグナルの待機は、待機時間全体と比較してできる限り低い割合である必要があります。特定のリソースがプロセッサ リソースを待機する時間は、待機時間全体からシグナルの待機時間を減算することで求められます。この値は、待機時間全体の約 20% 未満である必要があります。

sys.dm_exec_sessions DMV は、SQL Server 上で開かれているすべてのセッションを表示します。この DMV では、各セッションのパフォーマンスの概要と、各セッションの開始後に実行されたすべての処理を確認できます。これらのデータには、セッションが待機に費やした時間、CPU 使用率の合計、メモリ使用量、読み取りと書き込みの回数などがあります。また、ログイン、ログイン時間、ホスト コンピュータ、およびセッションが最後に SQL Server の要求を発行した時刻も確認できます。

sys.dm_exec_sessions DMV を使用すると、アクティブなセッションのみを確認できるため、CPU 使用率が高い場合は、まずこのビューを参照してください。まず CPU 時間が長いセッションを確認します。次にその処理を実行しているアプリケーションとユーザーを確認し、さらに細かく調査していきます。sys.dm_exec_sessions DMV と sys.dm_exec_requests DMV の両方を使用することで、sp_who および sp_who2 ストアド プロシージャによって取得できる情報のほとんどを取得できます。sql_handle 列を使用してこのデータを sys.exec_sql_text 動的管理関数 (DMF) と結合すると、セッションが現在実行しているクエリを取得できます。図 3 のコードは、サーバーの現在の状態を確認するために、このデータをまとめて取得する方法を示しています。

Figure 3 サーバーの動作状況を特定する

SELECT es.session_id
    ,es.program_name
    ,es.login_name
    ,es.nt_user_name
    ,es.login_time
    ,es.host_name
    ,es.cpu_time
    ,es.total_scheduled_time
    ,es.total_elapsed_time
    ,es.memory_usage
    ,es.logical_reads
    ,es.reads
    ,es.writes
    ,st.text
FROM sys.dm_exec_sessions es
    LEFT JOIN sys.dm_exec_connections ec 
        ON es.session_id = ec.session_id
    LEFT JOIN sys.dm_exec_requests er
        ON es.session_id = er.session_id
    OUTER APPLY sys.dm_exec_sql_text (er.sql_handle) st
WHERE es.session_id > 50    -- < 50 system sessions
ORDER BY es.cpu_time DESC

このステートメントは、調査が必要なアプリケーションを特定する際に役立ちます。あるアプリケーションのすべてのセッションの CPU、メモリ、読み取り、書き込み、論理読み取りを比較し、CPU リソースが他のリソースよりも多く使用されていると判断した場合、そのアプリケーションの SQL ステートメントを調査します。

アプリケーションの SQL ステートメントの履歴を追跡する場合、SQL Server トレースを使用します。SQL Server Profiler ツールやトレース システム ストアド プロシージャを使用してこれらの履歴を記録することで、現在の状態を評価できます (詳細については、補足記事「SP によるトレース」を参照してください)。Profiler を確認して、CPU 使用率が高いステートメントのほか、ハッシュや並べ替えの警告、キャッシュの欠落など、赤いフラグでマークされている事項を調べる必要があります。これにより、リソース使用率が高い SQL ステートメントや期間を絞り込むことができます。Profiler は、SQL ステートメントのテキスト、実行プラン、CPU 使用率、メモリ使用量、論理読み取り、書き込み、クエリ プランのキャッシュ、再コンパイル、キャッシュからのクエリ プランの取り出し、キャッシュの欠落、テーブルとインデックスのスキャン、統計の欠落、およびその他のさまざまなイベントを追跡できます。

sp_trace ストアド プロシージャまたは SQL Server Profiler を使用してデータを収集したら、通常はデータベースを使用します。このデータベースにトレース データを格納するには、トレースの完了後にデータを読み込むか、データベースへの書き込みを実行するようにトレースを構成します。トレースの完了後にデータベースにデータを格納するには、fn_trace_getinfo という SQL Server システム関数を使用します。この方法のメリットは、複数の方法でデータの照会と並べ替えを行い、最も CPU 使用率が高い SQL ステートメント、最も読み取り数が多い SQL ステートメント、再コンパイルの回数、およびその他の多くの情報を確認できることです。この関数を使用して、Profiler のトレース ファイルをテーブルに読み込む例を次に示します。既定では、指定したトレースのすべてのトレース ファイルが、作成された順序で読み込まれます。

SELECT * INTO trc_20070401
FROM fn_trace_gettable('S:\Mountpoints\TRC_20070401_1.trc', default);
GO

まとめ

これまで見てきたとおり、CPU 使用率が高い場合でも、必ずしも CPU がボトルネックになっているとは限りません。CPU 使用率が高い場合、他のさまざまなアプリケーションやハードウェアがボトルネックになっている可能性もあります。他のカウンタが正常な値であるにもかかわらず CPU 使用率が高い場合は、システム内に原因があるかどうかを調査し、解決策 (CPU の追加購入や SQL コードの最適化など) を特定します。どのような作業を行うにしても、あきらめないことが大事です。この記事のヒントを参考に、いくつかの調査を行って対策を実践すれば、SQL Server の CPU 使用率の最適化という実行プランを達成することは可能です。

Zach Nichter は、10 年以上の経験を持つ SQL Server プロフェッショナルです。DBA、チーム リード、マネージャ、コンサルタントなど、さまざまな SQL Server サポートの職を務めてきました。現在は、Levi Strauss & Co. の DBA アーキテクトとして、SQL Server のパフォーマンス、管理、アーキテクチャ、およびその他の戦略を主導しています。Zach は、www.sqlcatch.com で公開されているビデオ ブログの作者でもあります。

© 2008 Microsoft Corporation and CMP Media, LLC. All rights reserved; 許可なしに一部または全体を複製することは禁止されています.