[INF] Microsoft SQL Server パフォーマンスの最適化

文書翻訳 文書翻訳
文書番号: 110352 - 対象製品
この記事は、以前は次の ID で公開されていました: JP110352
すべて展開する | すべて折りたたむ

目次

概要

Microsoft SQL Server のパフォーマンスを最も効果的に最適化するには、さまざまな状況下で、パフォーマンスが最大限に向上する領域を特定し、その領域を集中的に分析する必要があります。そうでないと、大きな向上を見込めない箇所に、貴重な時間と労力を費やす可能性があります。

ここでは、マルチユーザーの同時実行によって生じるパフォーマンスの問題は扱いません。この問題は、独立した複雑なトピックであり、SQL Server Version 4.2x の『Programmer's Reference for C』の「付録 E Maximizing Database Consistency and Concurrency」や「サポート技術情報」 (Microsoft Knowledge Base) の資料で別に扱われています。このトピックは、バージョン 6.0 のマニュアルには記載されていませんが、同じタイトルのドキュメントが MSDN (Microsoft Developer Network) CD に含まれています。

この資料では、理論的な議論ではなく、ここ数年間に Microsoft SQL Server のサポート部門が経験した実稼働環境での実践的な領域に焦点を当てています。

SQL Server のパフォーマンスを最も向上させるのは、データベースの論理設計、インデックス設計、クエリ設計、およびアプリケーション設計という一般的な領域であるということが経験上わかっています。反対に、これらの領域での欠陥が、パフォーマンスの最大の問題になる場合が数多くあります。パフォーマンスについて考える場合、まずこの領域を集中的に検討する必要があります。比較的短い時間を費やすだけで、パフォーマンスが飛躍的に向上することがよくあります。

メモリ、キャッシュ バッファ、ハードウェアなどのその他のシステム レベルのパフォーマンスの問題もある程度検討の対象にする必要があり、これらの領域からパフォーマンスの向上が見込めることは経験上わかっています。しかし、SQL Server では、使用可能なハードウェア リソースの大部分が自動的に管理されるため、手作業によるシステム レベルの広範なチューニングの必要性とその結果生じる効果は大きくありません。

Microsoft SQL Server 6.0 は、大容量のメモリ、対称型マルチプロセッシング、並列データ スキャン、オプティマイザの機能強化、ディスク ストライピングなどのプラットフォーム層でのパフォーマンス向上に関する新機能を提供しています。しかし、このような機能を使用したパフォーマンスの向上には限界があります。コンピュータが高速であっても、非効率なクエリや、設計が不十分なアプリケーションではパフォーマンスは低下します。SQL Server 6.0 には、このようなパフォーマンスを向上する機能が追加されていますが、最も重要なことはデータベース設計、インデックス設計、クエリ設計、およびアプリケーション設計を最適化することです。

パフォーマンス上の大部分の問題は、サーバー側だけに焦点を当てて解決しても、問題がすべて解決したことにはなりません。サーバーは、クライアントからどのようなクエリが送信されたかを調べ、それに応じてどのようなロックをかけるかを制御する、いわばクライアントの "操り人形" にすぎません。サーバー側でできるチューニングもありますが、パフォーマンスの問題を適切に解決するには、通常その問題でクライアントが演じる主要な役割を認識し、クライアント アプリケーションの動作を分析することが必要です。

詳細

これまでの経験を基に、パフォーマンスの大幅な向上が得られる提案を以下に示します。

データベース論理設計の正規化

データベースの論理設計を適切に正規化することにより、最高のパフォーマンスを得られます。正規化されたデータベースには列数の少ないテーブルが数多く含まれることになります。正規化されていないデータベースは、列数の多いテーブルが含まれ、テーブルの数は少なくなります。高度に正規化されたデータベースは、一般的に複雑なリレーショナル結合が関連付けられ、パフォーマンスを低下させる可能性があります。ただし、SQL Server のオプティマイザは非常に効果的で、効率的なインデックスさえ使用していれば効果的な結合がすばやく選択されます。

正規化には次のような利点があります。
  • テーブルの列数が少ないので、並べ替えやインデックスの作成が高速です。
  • テーブル数が多いので、クラスタ化インデックスがより有効になります。
  • インデックスの範囲が小さくなり、よりコンパクトになる傾向があります。
  • テーブルごとのインデックス数が少なくなり、UPDATE のパフォーマンスが向上します。
  • NULL や冗長データが少なくなり、データベースがより小型化されます。
  • 必要なテーブル ロックが影響するデータが少なくなるので、DBCC 診断を同時実行することによる影響が減少します。
SQL Server では、適切な正規化によりパフォーマンスが低下することはなく、むしろ向上します。正規化が進むと、データを取り出すのに必要な結合の数と複雑さが増加します。経験に基づく大まかな規則では、多くのクエリが 4 方向以上の結合を持つようになるまで、正規化のプロセスを進めることをお勧めします。

データベースの論理設計が確定し、全体的な再設計が現実的ではない場合、データベースを分析し、ボトルネックになる大きなテーブルが存在するときは、このテーブルを選択して正規化します。ストアド プロシージャを使用してデータベースにアクセスしている場合、このようなスキーマの変更がアプリケーションに影響を与えることはありません。ストアド プロシージャを使用していない場合は、単一のテーブルのように見えるビューを作成して、変更を隠すこともできます。

効果的なインデックス設計の使用

多くの非リレーショナル システムとは異なり、リレーショナル インデックスはデータベースの論理設計の一部とは考えられていません。インデックスの削除、追加、および変更は、データベース スキーマまたはアプリケーション設計に影響を与えることはなく、パフォーマンスのみに影響します。効果的なインデックス設計は、SQL Server のパフォーマンス向上において非常に重要です。このため、ためらわずに、別のインデックスを使用してみることをお勧めします。

多くの場合、オプティマイザは、最も効果的なインデックスを選択します。インデックス設計の全体的な考え方としては、十分検討して選択したインデックスをオプティマイザに提供し、オプティマイザが正しい決定を下すことを信頼します。この結果、分析時間が短縮され、さまざまな状況下で優れたパフォーマンスが得られます。

インデックス設計に関する推奨事項を以下に示します。
  • オプティマイザが最重要視する SQL クエリの WHERE 句を調べます。

    WHERE 句内の各列がインデックスの候補になる可能性があります。調べるクエリが多すぎる場合は、代表的なクエリのセットを選択するか、低速のクエリだけを選択します。開発ツールが透過的に SQL コードを作成している場合、選択は容易ではありません。このようなツールの大部分は、デバッグ用に、生成した SQL の構文をファイルまたは画面にログとして出力できます。ツールにこのような機能が備わっているかどうかは、ツールの製造元に問い合わせてください。
  • 対象範囲の少ないインデックスを使用します。

    対象範囲の少ないインデックスは、複数列の複合インデックスよりも効果的です。対象範囲の少ないインデックスは、ページごとに多くの行を持ち、インデックス レベルも少ないので、パフォーマンスが向上します。

    オプティマイザは、数百または数千の可能性のあるインデックスおよび結合を高速、かつ効果的に分析できます。対象範囲の少ないインデックスを数多く使用することにより、オプティマイザの選択肢が多くなり、通常はパフォーマンスの向上に役立ちます。対象範囲が広く、複数の列を含むインデックスを使用して、インデックスの数を少なくすると、オプティマイザの選択肢が少なくなり、パフォーマンスが低下することがあります。

    一般的には、すべての条件をカバーするようなクエリを重要視する方法を採用しないようにします。SELECT 句内のすべての列が非クラスタ化インデックスでカバーされていると、オプティマイザはこれを認識し、非常に優れたパフォーマンスを提供するのは確かです。しかし、この結果非常に広範囲を対象とするインデックスになり、オプティマイザがこの方法を使用するであろうという可能性に頼りすぎています。一般的には、対象範囲の少ないさまざまなインデックスを数多く使用すると、広い範囲のさまざまなクエリによりよいパフォーマンスを提供できます。

    インデックスの更新にはオーバーヘッドが必要なので、インデックス数を適切な読み取りパフォーマンスが得られる程度にする必要があります。更新中心の操作であっても、書き込みよりも読み取りの回数の方がはるかに多くなります。ですから、効果があると考えられるインデックスがあれば、ためらわずに新しいインデックスを試してください。インデックスはいつでも削除できます。
  • クラスタ化インデックスを使用します。

    クラスタ化インデックスを適切に使用すると、パフォーマンスが大幅に向上します。UPDATE 操作や DELETE 操作も多くの読み取りを必要とするので、一般的にはクラスタ化インデックスを使用すると高速になります。テーブルごとに 1 つしかクラスタ化インデックスが許可されないので、このインデックスは慎重に使用してください。多くの行を返すクエリや、値の範囲を必要とするクエリは、クラスタ化インデックスにより高速化できる可能性があります。


          SELECT * FROM PHONEBOOK
          WHERE LASTNAME='SMITH'
    
          -or-
    
          SELECT * FROM MEMBERTABLE
          WHERE  MEMBER_NO > 5000
           AND MEMBER_NO < 6000
    
    						
    一方、上記の例のようなクエリが一般的な場合、LASTNAME 列や MEMBER_NO 列は非クラスタ化インデックスの候補としては適していません。非クラスタ化インデックスは返される行が少ない列で使用してください。
  • 列の一意性を調べます。

    これは、どの列がクラスタ化インデックスまたは非クラスタ化インデックスの候補になるのか、またはインデックスを付けないのかを判断するのに役立ちます。

    列の一意性を調べるクエリを以下に示します。
          SELECT COUNT (DISTINCT COLNAME)
          FROM TABLENAME
    
    						
    このクエリは、列内の一意値の数を返します。この結果をテーブル内の合計行数と比較します。10,000 行のテーブルで、一意値の数が 5,000 の場合は、この列は非クラスタ化インデックスの候補に適しています。同じテーブルで、一意値の数が 20 の場合は、クラスタ化インデックスに適しています。一意値の数が 3 の場合は、インデックスは必要ありません。これは単なる例で、厳密な規則ではありません。クエリの WHERE 句で使用している各列にインデックスを付けることを覚えておいてください。
  • インデックスが付けられた列内のデータ分布を調べます。

    一意値が少ない列にインデックスを付ける場合、またはそのような列で JOIN を実行する場合に、クエリの実行時間が長くなることがあります。これは、データやクエリ自身が持つ根本的な問題で、通常このようなことが発生する状況を認識しないと解決できません。たとえば、姓をアルファベット順に並べた電話帳を考えてみてください。その市のすべての人の姓が「Smith」または「Jones」だけだった場合、ある人を探し出すのはたいへんな作業です。列の一意性のある 1 つの側面を象徴するような上記のクエリの他に、インデックス付きのキー値のデータ分布を調べるために GROUP BY クエリを使用できます。このクエリにより、データの分布状況を正確に知ることができ、オプティマイザがデータを表示する方法を予測できます。

    以下のクエリの例は、インデックス付きのキー値のデータ分布を調べるもので、COL1 と COL2 の 2 つの列がキーであると想定しています。
          SELECT COL1, COL2, COUNT(*)
          FROM TABLENAME
          GROUP BY COL1, COL2
    
    						
    このクエリは、各値のインスタンスの数を持つ行を、キー値ごとに 1 行返します。返される行数を少なくするには、HAVING 句を使用して一部を除外するようにします。以下に HAVING 句の例を示します。
          HAVING COUNT(*) > 1
    
    						
    この例では、一意キーを持つすべての行を除外します。

    1 つのクエリが返す行数も、インデックスを選択する重要な要素になります。オプティマイザは、非クラスタ化インデックスでは返される行ごとに少なくとも 1 ページの入出力が行われると想定します。この比率では、単にテーブル全体をスキャンする方が効率的です。このため、結果セットのサイズを制限したり、クラスタ化インデックスを使用して大量の結果を返すようにしたりします。
インデックスを使用すれば必ずパフォーマンスが向上し、インデックスを使用しないとパフォーマンスが低下するとは限りません。インデックスを使用すれば最善のパフォーマンスを生み出すことにつながるならば、オプティマイザの仕事は利用できるすべてのインデックスを使用するだけという、非常に単純なものになります。実際には、インデックスを使用したデータの取得で不適切な選択を行うと、パフォーマンスは著しく低下します。そのため、オプティマイザの仕事は、パフォーマンスが向上するようなインデックスを使用したデータ取得を選択し、パフォーマンスの低下を招くようなインデックスを使用したデータの取得を防ぐようにすることです。

効果的なクエリ設計の使用

ある種のクエリは、本質的にリソースを集中的に使用します。このことは、特に SQL Server に限らず、大部分のリレーショナル データベース管理システム (RDBMS) に共通する、データベースとインデックスの根本的な問題に関連しています。オプティマイザは、できるだけ効率的な形式でクエリを実装するので、クエリが非効率になることはありません。しかし、クエリがリソースを集中的に使用する場合、SQL のひとまとめに処理するという性質により非効率に見えることがあります。オプティマイザの機能がどれほど高くても、クエリ構成の内在的なリソースのコストを取り除くことはできません。この種のクエリは、その性質上、単純にクエリと比較すると、コストは低くありません。SQL Server は最適なアクセス プランを使用しますが、元来可能な範囲に制限されます。

以下に例を示します。
  • 大きな結果セット
  • IN、NOT IN、および OR クエリ
  • 一意性が極端に低い WHERE 句
  • != (等しくない) 比較演算子
  • SUM などの特定の列関数
  • WHERE 句内での式またはデータ変換
  • WHERE 句内のローカル変数
  • GROUP BY を使用した複雑なビュー
さまざまな要因により、これらのクエリ構成の一部を使用する必要性が生じます。リソースの使用率の高いクエリを適用する前に、オプティマイザが結果セットを制限できれば、これらのクエリ構成の影響は軽減されます。以下にその例を示します。

リソース使用率が高い例
   SELECT SUM(SALARY) FROM TABLE
				

リソース使用率が低い例
   SELECT SUM(SALARY) FROM TABLE WHERE
   ZIP='98052'
				

リソース使用率が高い例
   SELECT * FROM TABLE WHERE
   LNAME=@VAR
				

リソース使用率が低い例
   SELECT * FROM TABLE
   WHERE LNAME=@VAR AND ZIP='98052'
				

最初の例では、SUM 演算はインデックスを使用しても高速化できません。各行を読み取り、合計を計算する必要があります。ZIP 列にインデックスがあると仮定すると、オプティマイザは SUM を適用する前に、この列を使用して内部的に結果セットを制限します。この結果、高速になります。

2 番目の例では、ローカル変数は実行時まで解決されません。ただし、オプティマイザは、実行時までアクセス プランの選択を遅延できないので、コンパイル時にアクセス プランを選択する必要があります。しかし、コンパイル時にアクセス プランを作成するときは、@VAR の値がわからないので、その後のインデックス選択の入力としてこの変数を使用することはできません。

ここで示したパフォーマンス強化の手法では、AND 句を使用して結果セットを限定しています。別の手法として、ストアド プロシージャを使用し、そのストアド プロシージャのパラメータとして @VAR の値を渡す方法があります。

1 つの非常に複雑なクエリよりも、中間結果を格納する一時テーブルを使用する単純なクエリのグループを使用する方が効率的な場合もあります。

ほとんどの RDBMS では、結果セットが大きいと、コストが高くなります。参照により最終的なデータ選択を行うために大きな結果セットをクライアントに返すことは避けるようにします。データベース システムが予定していた機能を実行できるように結果セットのサイズを制限することがより効果的です。結果セットのサイズを小さくすると、ネットワークの入出力も少なくなり、低速のリモート通信リンク経由でもアプリケーションを展開することができます。また、ユーザー数を増加に伴なってアプリケーションの規模を拡大する場合、同時実行に関連するパフォーマンスも向上します。

効果的なアプリケーション設計の使用

SQL Server のパフォーマンスに関してアプリケーション設計が演じる役割をあまりおおげさに考える必要はありません。アプリケーション設計が演じる主要な役割をサーバー中心に考えるのではなく、実質的にアプリケーションを制御しているクライアントを中心に考えた方がより正確になります。サーバーは、クライアントの操り人形にすぎません。クエリの種類、クエリが送信されるタイミング、結果を処理する方法など、すべてにおいて、SQL Server はクライアントのコマンドに影響を受けます。つまり、サーバーではロックの種類と期間、入出力の量、および CPU の負荷に主に影響を受け、パフォーマンスが良いか悪いかが決まります。

このため、アプリケーションの設計段階で適切な判断を下すことが重要です。しかし、クライアント アプリケーションに対する変更が不可能に思える市販のアプリケーションを使用していてパフォーマンスの問題に直面した場合、パフォーマンスに影響を与える根本的な要因を変更できません。つまり、クライアントが最も主要な役割を演じており、多くのパフォーマンスの問題は、クライアントを変更しないと解決できません。

十分検討して設計されたアプリケーションでは、SQL Server は数千もの同時実行ユーザーをサポートできます。アプリケーションの設計が不十分な場合、非常に優れたサーバー プラットフォームを使用しても、ごく小数のユーザーにも対応できなくなります。

以下の推奨事項に従ってクライアント アプリケーションを設計することで、良好な SQL Server のパフォーマンスを得ることができます。
  • 小さな結果セットを使用します。クライアントで参照するために不必要に大きな結果セット (たとえば、数千行もの) を取得すると、CPU とネットワーク入出力の負荷が増大し、アプリケーションをリモートで使用しにくくなり、さらにマルチ ユーザーのスケーラビリティが制限されます。小さな結果セットを生成するクエリが実行されるように、ユーザーに十分な入力を求めるアプリケーションを設計することをお勧めします。

    これを実現するアプリケーション設計手法としては、クエリを作成する際のワイルドカードの使用を制限すること、特定の入力フィールドを必須とすること、十分な検討を行っていないクエリの使用を禁止すること、などがあります。
  • DB-Library を使用するアプリケーションで、dbcancel() を適切に使用します。すべてのアプリケーションは、実行中のクエリを中止できる必要があります。クエリを取り消すために、ユーザーが強制的にクライアント コンピュータを再起動する必要があるようなアプリケーションを作成しないようにします。この原則に従わない場合、解決できないパフォーマンスの問題が発生することがあります。dbcancel() を使用する場合、トランザクション レベルについては十分な注意が必要です。詳細については、「サポート技術情報」 (Microsoft Knowledge Base) の次の資料を参照してください。
    117143 [SQL] いつ、どのように dbcancel()、sqlcancel() を使用するか
    ODBC sqlcancel() 呼び出しを使用している ODBC アプリケーションにも同じことが言えます。
  • 処理結果をすべて完了させます。クエリを取り消さずに処理を停止するようなアプリケーションは設計しないようにします。そのような市販のアプリケーションも使用しないようにします。このようなアプリケーションでは、一般的にブロックが発生し、パフォーマンスが低下します。
  • クエリのタイムアウトを必ず実装するようにします。無限に実行されるクエリを許可しないようにします。適切な DB-Library または ODBC 呼び出しを使用して、クエリ タイムアウトを設定します。DB-Library では dbsettime() 呼び出しを、ODBC では SQLSetStmtOption() 呼び出しを使用します。
  • サーバーに送信する SQL ステートメントを明確に制御できないアプリケーション開発ツールを使用しないようにします。クエリの取り消し、クエリ タイムアウト、完全なトランザクション制御などの重要な機能が提供されている場合を除き、より高度なオブジェクトに基づいて透過的に SQL ステートメントを作成するツールは使用しないようにします。アプリケーション自体で "透過的な SQL" が生成される場合、良好なパフォーマンスの維持やパフォーマンスの問題の解決ができないことがほとんどです。このようなアプリケーションでは、トランザクションやロックの問題を明示的に制御できないため、パフォーマンスの計画においては重大な問題となります。
  • 意志決定支援用のクエリとオンライン トランザクション処理 (OLTP) のクエリを混在させないようにします。
  • クエリを取り消すために、ユーザーが強制的にクライアント コンピュータを再起動する必要があるようなアプリケーションは設計しないようにします。そのような市販のアプリケーションも使用しないようにします。これは、孤立した接続が発生する可能性があるため、解決が困難なさまざまなパフォーマンス上の問題を引き起こします。詳細については、「サポート技術情報」 (Microsoft Knowledge Base) の次の資料を参照してください。
    137983 [SQL] INF: SQL Server 内の無効な接続のトラブルシューティング

パフォーマンスの低下を分析する手法

メモリ容量、ファイル システムの種類、プロセッサの数や種類など、システム レベルでサーバーのパフォーマンスをチューニングするだけで、パフォーマンスの問題を解決できれば簡単です。しかし、Microsoft SQL Server サポート部門の経験では、大部分のパフォーマンスの問題はこの方法では解決できません。パフォーマンスの問題を解決するには、アプリケーションや、アプリケーションがデータベースに対して実行しているクエリ、これらのクエリとデータベース スキーマとの対話的な処理の方法を解析する必要があります。

まず、低速のクエリを特定します。実際には少数の SQL クエリのみが低速であっても、アプリケーション全体の処理速度が遅く見える場合があります。一般的には、問題点を切り分けて低速のクエリを特定しなければ、パフォーマンスの問題を解決することはできません。SQL を透過的に生成する開発ツールがある場合は、そのツールの診断モードやデバッグ モードを使用して、生成される SQL を捕捉します。多くの場合トレース機能が使用できますが、マニュアルに記載されていない場合もあります。アプリケーションが生成する SQL ステートメントを監視するトレース機能が存在するかどうかを確認するには、そのアプリケーションのテクニカル サポートに問い合わせてください。

埋め込み型 SQL を使用するアプリケーション開発ツールでは、生成される SQL を表示できるため、この作業がはるかに容易です。

開発ツールやエンドユーザー アプリケーションでトレース機能が提供されていない場合は、代わりに以下の方法を使用できます。
  • SQL Server 4.2x の『トラブルシューティング ガイド』、SQL Server 6.0 の『Transact-SQL リファレンス』の指示に従って 4032 トレース フラグを使用します。このフラグを使用すると、サーバーに送信される SQL ステートメントを SQL エラー ログにキャプチャできます。
  • Systems Management Server に含まれる Microsoft ネットワーク モニタなどのネットワーク アナライザを使用してクエリを監視します。
  • ODBC アプリケーションでは、ODBC アドミニストレータ プログラムを使用して、ODBC 呼び出しのトレースを選択します。詳細については、ODBC のマニュアルを参照してください。
  • DB-Library 層または ODBC 層で SQL をインターセプトするサードパーティのクライアント側ユーティリティを使用します。このようなユーティリティの 1 つに Blue Lagoon Software 社の SQL Inspector があります。
  • Microsoft TechNet CD にサンプルとして提供されている SQLEye 分析ツールを使用します。

    注 : SQLEye は、マイクロソフト製品サポート サービスではサポートしていません。
低速のクエリを特定できたら、以下の手順を実行します。
  • ISQL などのクエリ ツールを使用して、低速であると特定したクエリを単独で実行し、それが実際に低速であることを確認します。一般的には、ISQL とローカル パイプを使用してサーバー コンピュータ上で実行し、結果をファイルにリダイレクトするのが最善の方法です。これにより、ネットワーク入出力や画面入出力、アプリケーションによる結果のバッファリングなどの複雑な要因をなくすことができます。
  • SET STATISTICS IO ON を使用して、クエリが消費している入出力を調べます。論理ページへの入出力回数に注目します。オプティマイザの目標は、入出力回数を最小限にすることです。論理入出力の回数を記録します。この回数は、パフォーマンスの向上を計測する基準値になります。一般的には、SET SHOWPLAN ON を使用するよりも、STATISTICS IO の出力だけに注目して、さまざまな種類のクエリやインデックスで実験を行う方が効果的です。SHOWPLAN の出力を解釈し、効果的に適用するには、ある程度の学習が必要で、実証的なテストを行う方が時間を効率的に使用できます。これらの簡単な推奨方法でパフォーマンスの問題が解決しない場合は、SHOWPLAN を使用して、オプティマイザの動作をより詳細に調べます。
  • クエリにビューまたはストアド プロシージャが関連している場合は、ビューまたはストアド プロシージャからクエリ取り出し、単独で実行します。この結果、さまざまなインデックスを使用して実験することにより、アクセス プランを変更できます。さらに、問題がクエリ自体にあるのか、それともオプティマイザがビューまたはストアド プロシージャを処理する方法に問題があるのかを切り分けることもできます。クエリ自体に問題があるわけでなく、ビューまたはストアド プロシージャの一部としてクエリが実行されるときだけ問題が生じる場合は、クエリを単独で実行することにより判別できます。
  • 関連するテーブルのトリガが、実行時に入出力を透過的に生成している可能性に注目します。低速のクエリに含まれるトリガをすべて削除します。この結果、クエリ自体に問題があるのか、トリガまたはビューに問題があるのかを判別でき、どこに注目すればよいのかがわかります。
  • 低速のクエリが使用しているテーブルのインデックスを調べます。前述した手法を使用して、インデックスとして優れているのかどうかを判定し、必要に応じて変更します。最初の試みとして、WHERE 句の各列にインデックスを付けます。単に WHERE 句内の列にインデックスが付けられていない、またはその列に付けられているインデックスが適切でないことにより、パフォーマンスの問題が生じることがあります。
  • 前述したクエリを使用して、WHERE 句内の列ごとに、特にインデックスが付けられた列で、データの一意性と分布を調べます。多くの場合、クエリ、テーブル、インデックスおよびデータを単純に調査することにより、問題の原因がすぐに判明します。たとえば、3 つか 4 つしか一意値がないキーにインデックスを付けている場合、そのような列で JOIN を実行している場合、またはクライアントに極端に多くの行を返している場合に、パフォーマンスの問題が生じることがよくあります。
  • これらの調査に基づき、アプリケーション、クエリ、またはインデックスに必要な変更を加えます。変更を行った後にクエリを再実行し、入出力回数が変化したかどうかを調べます。
  • パフォーマンスの向上が認められたら、メイン アプリケーションを実行し、全体的なパフォーマンスが向上したかどうかを確認します。
プログラムで、入出力または CPU に制限される動作を調べます。クエリが入出力や CPU に制限されているかどうかを調べることが役立つことがよくあります。これにより、実際にボトルネックになっている点に向上のための労力を集中できます。たとえば、クエリが CPU に制限されている場合、SQL Server にメモリを追加しても、パフォーマンスが向上する可能性はありません。メモリを追加することにより向上するのは、キャッシュ ヒット率だけです。この場合は、キャッシュ ヒット率は既に高いと考えられます。

クエリの動作が入出力に制限されているか、CPU に制限されているかを調べるには、以下の方法を使用します。
  • Windows NT パフォーマンス モニタを使用して、入出力と CPU の使用状況を監視します。LogicalDisk オブジェクトの "% Disk Time" カウンタのすべてのインスタンスを監視します。さらに、System オブジェクトの "% Total Processor Time" カウンタを監視します。有効なディスク パフォーマンス情報を調べるには、この設定の前に、コマンド プロンプトから diskperf -Y コマンドを実行して Windows NT DISKPERF 設定を有効にし、システムを再起動する必要があります。詳細については、Windows NT のマニュアルを参照してください。
  • クエリの実行中に、CPU グラフが一貫して高い値 (たとえば 70% 以上) を示し、"% Disk Time" 値が一貫して低い値を示す場合は、CPU の制限を受けています。
  • クエリの実行中に、CPU グラフが一貫して低い値 (たとえば 50% 未満) を示し、"% Disk Time" 値が一貫して高い値を示す場合は、入出力の制限を受けています。
  • CPU のグラフを STATISTICS IO 情報と比較します。

まとめ

SQL Server は、大規模なデータベースで、非常に高いパフォーマンスを実現する能力を持っています。SQL Server 6.0 の場合はこれが特に顕著です。このパフォーマンスの潜在能力を引き出すには、データベース、インデックス、クエリ、およびアプリケーションを効率的に設計する必要があります。これらの領域が、パフォーマンスを大幅に向上するための最適な候補です。アプリケーションの規模を多くのユーザーが使用できるように拡張する場合、集中するマルチユーザーの負荷に対応できるように、各クエリをできる限り効率的にするように心がけてください。この資料のガイドラインに従って、クライアント アプリケーションの動作やアプリケーションで実行されるクエリを調べ、インデックスを使用した実験を行うことを強くお勧めします。方法論に則った手法でパフォーマンスの問題の分析を行うことにより、比較的短い時間を費やすだけで、パフォーマンスが飛躍的に向上することがよくあります。

プロパティ

文書番号: 110352 - 最終更新日: 2005年10月28日 - リビジョン: 3.1
この資料は以下の製品について記述したものです。
  • Microsoft SQL Server 4.21a Standard Edition
  • Microsoft SQL Server 6.0 Standard Edition
  • Microsoft SQL Server 6.5 Standard Edition
キーワード:?
kbinfo kbother KB110352
"Microsoft Knowledge Baseに含まれている情報は、いかなる保証もない現状ベースで提供されるものです。Microsoft Corporation及びその関連会社は、市場性および特定の目的への適合性を含めて、明示的にも黙示的にも、一切の保証をいたしません。さらに、Microsoft Corporation及びその関連会社は、本文書に含まれている情報の使用及び使用結果につき、正確性、真実性等、いかなる表明・保証も行ないません。Microsoft Corporation、その関連会社及びこれらの権限ある代理人による口頭または書面による一切の情報提供またはアドバイスは、保証を意味するものではなく、かつ上記免責条項の範囲を狭めるものではありません。Microsoft Corporation、その関連会社 及びこれらの者の供給者は、直接的、間接的、偶発的、結果的損害、逸失利益、懲罰的損害、または特別損害を含む全ての損害に対して、状況のいかんを問わず一切責任を負いません。(Microsoft Corporation、その関連会社 またはこれらの者の供給者がかかる損害の発生可能性を了知している場合を含みます。) 結果的損害または偶発的損害に対する責任の免除または制限を認めていない地域においては、上記制限が適用されない場合があります。なお、本文書においては、文書の体裁上の都合により製品名の表記において商標登録表示、その他の商標表示を省略している場合がありますので、予めご了解ください。"
サポート期間が終了した「サポート技術情報」資料に関する免責事項
この資料は、マイクロソフトでサポートされていない製品について記述したものです。そのため、この資料は現状ベースで提供されており、今後更新されることはありません。

フィードバック

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com