次の方法で共有


ASP アプリケーションのパフォーマンス向上

J.D. Meier
Microsoft Corporation

March 28, 2000

目次
はじめに
ASP ページのパフォーマンス
コンポーネントのパフォーマンス
データ アクセスのパフォーマンス
IIS の設定
ストレス テスト
まとめ

はじめに

ASP アプリケーションのパフォーマンスを引き出すにはどうしたらよいかという開発者からの質問を受ける機会がしばしばあります。私は Active Server Pages (ASP) アプリケーションのパフォーマンスを評価する機会が多いので、問題を特定するための質問と推奨する改善策のセットを公開しようと思い立ちました。これらのヒントの中には常識のように思えるものもありますし、あまり知られていないものもありますが、すべて実世界での経験に裏付けられたものです。

ASP ページのパフォーマンス

Visual Basic オブジェクトをセッションスコープまたはアプリケーションスコープに格納していませんか

Visual Basic® とその他のシングルスレッド アパートメント (Single-Threaded Apartment: STA) オブジェクトは、ページ スコープでのみ使用すべきです。STA をセッション変数に格納すると、スレッド プールの目的に反して、オブジェクトはそのオブジェクトを作成したスレッドにロックされてしまいます。STA をアプリケーション スコープに格納すると、すべてのユーザーのアクセスが直列化されます。この問題の詳細については、以下の記事を参照してください。

Scripting.Dictionary をセッション スコープまたはアプリケーション スコープに格納していませんか

Scripting.Dictionary はアパートメント スレッドなので、ページ スコープでのみ使用すべきであり、さもないと深刻な直列化問題が発生します ( Q194803 "PRB: Scripting.Dictionary Object Fails in ASP Application Scope" Non-MSDN Online link を参照)。この制約は、通常、どんな Dictionaryであればセッション スコープまたはアプリケーション スコープで使用できるかという疑問を生みます。選択肢は限られていますが、Commerce Dictionary と LookupTable オブジェクトであれば使用できます。「Abridging the Dictionary Object: The ASP Team Creates a Lookup-Table Object」を参照してください。

ASP スクリプトの長さが数百行に達していませんか

スクリプトは 1 行ずつ解釈されるので、冗長なスクリプトを省いたり、より効率的なスクリプトを作成することによってパフォーマンスを高めることができます。1 つのページに数百行の長さの ASP スクリプトがある場合は、ユーザー サービス、ビジネス サービス、およびデータ サービスを分割した方がよいでしょう。

ASP スクリプトは入力を集めたり、出力を書式化するのに適していますが、ビジネスおよびデータ サービスについては、事前バインドや知的財産権の保護など、コンポーネントの方が利点が多いです。Jason Taylor は、彼の記事「Component vs. Component Part II Non-MS link」の中で、Windows Script Components (WSC) を中間ステップとして ASP スクリプトをカスタム コンポーネントに移植して、これによって得られた大幅なパフォーマンス向上について述べています。

コンポーネントを使用しない場合でも、サービスを関数によって分けることができます。たとえば、いくつかのテーブルを表示するスクリプトであれば、テーブルを生成する汎用関数を作成します。そうすれば、これらの関数をインクルードに入れることができ、将来、コンポーネントに移植するための下地を作ることができます。次のサンプルは、関数とインクルードを使用して保守性を高める例を示しています。

                  
<!-- #include file="Header.asp" -->
<!-- #include file="Footer.asp" -->
<script language="vbscript" runat="server">
 
      Sub Main()
             WriteHeader
             WriteBody
             WriteFooter
      End Sub

      Sub WriteBody()
     
      End Sub

      Main   'call sub Main
</script>

#include ファイルが大きすぎませんか

インクルード ファイルのサイズについて厳格なルールはありませんが、インクルードがどのように機能するかを理解することは、インクルードを効率的に使用しているかどうかを判断する上で役立ちます。ASP がインクルードを処理するときには、ファイル全体をメモリに読み込みます。ASP は、あなたが呼び出した関数だけでなく、拡張コード全体 (ページとインクルード) をキャッシュするので、インクルードが大きすぎると、メソッドを呼び出したり変数を検索するときに、非効率的で大きな名前空間を検索しなければならなくなります。このプロセスは、インクルードを使用するページごとに発生します。したがって、きめ細かなインクルードを作成すれば、どのページでインクルードを使用するか、きめ細く設定することができます。ASP によるインクルードの処理の詳細については、「The Implications of ASP #include Non-MS link」を参照してください。

グローバル変数を使用していませんか

グローバル変数を使用すると、ASP がメモリから値を取り出すために使用する名前空間が大きくなります。サブルーチンまたは関数の内部で宣言された変数の方が高速です。詳細については、「25+ ASP Tips to Improve Performance and Style」を参照してください。

スクリプトが ASP や HTML のあちこちに散在していませんか

サーバー側のコードとクライアント側のコードを行ったり来たりするのではなく、ASP サーバー側スクリプトはまとめておきましょう。このような "行ったり来たり" は、次のように HTML テーブルを書き出すときのように、ASP の単純な値で HTML を連結するときに起こります。

                  
<%    For iCtr = 1 to 10 %>
<TR><TD>Counting     <%= iCtr %></TD></TR>
<%    Next  %>

これを 1 つのスクリプト ブロックにまとめることで、コードのパフォーマンスを高めることができます。

                  
<%    For iCtr = 1 to 10  
Response.Write "<tr><td>Counting " & iCtr & "</td></tr>"
      Next
%>

このテクニックは、目に見えて大きなパフォーマンス向上をもたらすことが実証されています。

出力をバッファリングしていますか

バッファリングは、Windows 2000 ではデフォルトで有効になっていますが、Internet Information Server (IIS) 4.0 からアップグレードした場合は無効になっていることがあります。

バッファリングが有効な場合、ASP は処理が完了するまで待ってから応答を送信するので、ネットワークのラウンドトリップ回数とサーバー側の処理の遅延が削減されます。バッファリングが無効になっていると、ASP はクライアントからの TCP 確認応答を待つので、特に低速な接続ではパフォーマンスが著しく低下します。

バッファリングはスループットを高めますが、体感速度を低下させることがあります。体感速度が重要な場合は、Response.Buffer = False によって、または Response.Flush を呼び出すことによってバッファリングを無効にすることができます。

セッション状態を使用していますか

ASP のセッションは便利な機能ですが、スケーラビリティを制限します。セッションはユーザーごとにリソースを消費するので、1 台のボックスのスケーラビリティを制限します。セッション サイズは、主にセッション 変数に何を入れるかによって決まりますが、実際のコストはリソースの競合です。セッションはそれぞれが Web サーバー固有なので、アプリケーションの機種依存性も高めます。

多くの場合、隠しフォーム フィールドを使用するか、QueryStrings でデータを渡すことによって Session オブジェクトの使用を避けることができます ( Q175167 "HOWTO: Persisting Values Without Sessions" Non-MSDN Online link を参照)。これらの方法によってスケーラビリティを確保できますが、データの構造が複雑になるので、コーディングが難しくなることがあります。

もう 1 つの方法は、データベースの使用です。これはショッピング カートなど、より複雑な構造に適しています。ショッピング カートをデータベースに格納して、必要に応じて検索することができます。大規模なコマース サイトの多くがこの方法を採用しており、一意な ID をユーザーに送信して、必要なときにデータベースの情報を検索しています。この方法では、トランスペアレントにスケーラビリティを確保できます。また、1 台の Web サーバーでより多くのユーザーに対応でき、要求から次の要求までのパーシステンシー (保持性) をカートに持たせることができます。多くの開発者はデータベースへの再接続がパフォーマンスを低下させると考えているため、この方法を見過ごしていますが、こういう場合こそプーリングが役立ちます (プーリングについては下記を参照してください)。

使用しない場合は、セッション状態を無効にしていますか

アプリケーションがセッション に依存しない場合は、Web または仮想ディレクトリの セッション状態を ISM (インターネット サービス マネージャ) を通じて無効にしてください。セッション状態を無効にすると、ASP は大量のソース コードをスキップすることができ、オーバーヘッドを削減できます。

サイトのセッション状態を有効にする必要がある場合は、次のようなページ宣言を使用することによって、特定のページについて ASP が不必要にセッション情報をチェックしないようにすることができます。

                  
@EnableSessionState = False

フレームを使用するページでは、この方法を使用するとよいでしょう。ASP は同じセッションからの同時並行の要求を直列化するので、フレーム内の ASP ページはシーケンシャルにロードされます。@EnableSessionState によってセッションを無効にした場合は、フレームは同時並行でロードされます。

ASP 向けのサードパーティ コンポーネントを使用していますか

コンポーネントが ASP 向けに設計され、テストされたものかどうか、サードパーティ コンポーネント ベンダに問い合わせてください。「ASP テクノロジでのコンポーネントのトラブルシューティング」に、ASP 準拠のためのガイドラインが示されています。

何らかの形でデータをキャッシュしていますか

キャッシングは、Web アプリケーションのスケーラビリティを脅かすおそれがあるので、Web アプリケーション開発の中でも最も難しいものの 1 つです。何をキャッシュすべきかは、データの揮発性とスコープによって決まります。静的なデータやアプリケーション全体を通じて使用されるデータは、キャッシングの対象になります。頻繁に変更されるデータやユーザー固有のデータは、キャッシュしない方がよいでしょう。

アプリケーションのどこでデータをキャッシュすべきかは、アプリケーションの目的によって決まり、トレードオフを知っておく必要があります。たとえば、ActiveX® Data Objects (ADO) の Recordset のキャッシングには柔軟性があります。その場合でも配列を取り出したり、レコードセットを XML として保存できるからです。しかし、国名のリスト ボックスを表示するなど、同じ HTML を繰り返し描画するアプリケーションの場合は、データだけをキャッシュするよりも、HTML 文字列をアプリケーション スコープでキャッシュした方がよいでしょう。

キャッシングの柔軟性という点で、XML は確かに新しい扉を開きました。たとえば、 データを XML 文字列として格納して、必要に応じて XSL 変換を適用することができます。このテーマの詳細については、Paul Enfield の記事「Using Server-Side XSL for Early Rendering: Generating Frequently Accessed Data-Driven Web Pages in Advance」を参照してください。

設計の早期にストレス テストを行うと、使用すべきキャッシング テクニックを決める上で役立ちます。

CDO を使用していますか

Windows NT® 4.0 を使用している場合は、CDO-NTS および NT SP 5 以上を使用してください (Q214685 XFOR: CDONTS Not Thread-Safe, Crashes Under Stress を参照してください)。Collaboration Data Objects (CDO) は、Outlook Web Access を除いて、サーバー側での使用はテストされていません。Windows 2000 では、可能な場合は CDO for Windows 2000 (CDOSYS.dll) を使用してください。これはサーバー側の開発用に設計されています。以下の記事を参照してください。

配列の次元を変更していますか

一般に、配列の次元の変更は、必要以上に取り出すよりもコストがかかります。配列の次元の変更には、Visual Basic Scripting Edition (VBScript) を使用して、新しい配列のための空間を割り当てる必要があります。そして、配列の内容を確保するために Preserve 修飾子を使用していた場合は、元の配列から新しい配列にデータをコピーする必要があります。このことは、配列の次元を変更するには、余分なプロセッサ サイクルを消費するだけでなく、コピーのために 2 倍もメモリを使用することを意味します。しかし、最初に必要以上の空間を割り当てておけば (最初は 5 個の要素しか必要としない場合でも、128 個分の空間を割り当てます)、配列にデータを追加する場合、VBScript は新しい値を既存の配列に挿入するだけで済みます。

1 つのページで複数の言語を使用していませんか

あるページで複数の言語を使用するということは、そのページのために複数のスクリプト エンジンが必要なことを意味します。スクリプト エンジンはスレッド ローカル ストレージ (Thread Local Storage: TLS) を使用するので、複数のスレッドが 1 つのスクリプト エンジンの 1 つのインスタンスを同時に使用することはできません。したがって、1 つのページに対して同時に 5 つの要求があった場合、ASP は 5 つのスクリプト エンジンをインスタンス化します。エンジンが多いほどオーバーヘッドが増すので、1 つのページで使用する言語数を減らすことによってパフォーマンスを高めることができます。

長いルーチンを処理する前に Response.IsClientConnected をチェックしていますか

Response.IsClientConnected をテストすれば、クライアントがすでに接続していない場合はメソッドを終了することによって、CPU サイクルを待たなくてもよくなります。IIS 5.0 には、IIS 4.0 のような制約 (ブラウザにコンテンツを送信してからでなければプロパティをチェックできない) はありません。サンプル コードについては、 Q182892 "HOWTO: Use IsClientConnected to Check If Browser is Connected." Non-MSDN Online link を参照してください。

Server.MapPath を不必要に使用していませんか

Server.MapPathを要求すると、サーバーが処理すべき要求を増やすことになります。パフォーマンスを高めるには、Web サイトに導入するときに Server.MapPath を完全修飾されたパスに置き換えてください。

文字列を解析していますか

検証ルーチンで、書式設定関数で、および文字列をループする代わりに、正規表現を使用してください。正規表現の使用に関する具体的なアドバイスについては、「String Manipulation and Pattern Testing with Regular Expressions Non-MS link」を参照してください。

同じオブジェクトを何回も使用していますか

VBScript 5.0 には With ステートメントがあります。With ステートメントを使用すると、オブジェクトの名前を何度も修飾しなくても、特定のオブジェクトに対して一連のステートメントを実行することができます。詳細については、Windows Script Technologies Web サイト Non-MSDN Online link をご覧ください。

global.asa に空の Session_OnStart または Session_OnEnd メソッドが含まれていませんか

空のセッション イベントを省くと、ASP がトラバースしなければならないソース コードの量が減るので、パフォーマンスが向上します。

コンポーネントのパフォーマンス

オブジェクトを セッション スコープ または アプリケーション スコープに格納していませんか

ASP の セッション スコープ または アプリケーション スコープにオブジェクトを格納すると、スレッド間またはアクティビティ間で共有されることを目的としたオブジェクトでない場合、パフォーマンスとスケーラビリティに関する多くの問題が生じます。クライアント スレッドからの直接アクセスによってセッション変数またはアプリケーション変数で参照できるのは、敏捷なコンポーネント、すなわち Windows 2000 では Neutral としてマークされているコンポーネントだけです。Both としてマークされていて、フリースレッド マーシャラ (FTM) を集成するコンポーネントは、敏捷なコンポーネントと見なされます。FTM の集成については、「Agility in Server Components」を参照してください。ほかのスレッド モデルのコンポーネントをセッションス コープまたはアプリケーション スコープに格納すると、さまざまな制約が生じます。

すでに述べたように、Visual Basic やその他の STA コンポーネントは、ページ スコープ内でのみ使用すべきです。このルールに従えば、しっかり書かれた Visual Basic コンポーネントは優れたパフォーマンスを発揮します。シングルおよびフリースレッド コンポーネントは、アパートメントの境界を越えるマーシャルの際にセキュリティ問題が発生し、プロキシ/スタブのコストが高くなるため、お勧めできません。

詳細については、以下の記事を参照してください。

コンポーネント内で文字列を連結していますか

Visual Basic では、文字列の連結のために固定長文字列を使用してください。単に文字列を追加していくのはやめてください。何度も再割り当てすることになり、再割り当てはパフォーマンスを低下させます。

良くない例:

                  
Public Function BadConcatenation() As String
    Dim intLoop As Integer
    Dim strTemp As String      'this will be expensive
 
    For intLoop = 1 To 1000
        strTemp = strTemp & "<tr><td>Counting "
        strTemp = strTemp & CStr(i)
        strTemp = strTemp & "</td></tr>"
    Next intLoop

    BadConcatenation = strTemp
End Function

良い例:

                  
Public Function GoodConcatenation() As String
    Dim intCtr As Integer
    Dim intLoop As Integer
    Dim strTemp As String * 32000 'this improves performance

    intCtr = 1

    For intLoop = 1 To 1000

        Mid(strTemp, intCtr) = "<tr><td>Counting "
        intCtr = intCtr + 17

        Mid(strTemp, intCtr) = CStr(intLoop)
        intCtr = intCtr + Len(CStr(intLoop))

        Mid(strTemp, intCtr) = "</td></tr>"
        intCtr = intCtr + 10
    Next intLoop

    GoodConcatenation = strTemp
End Function

いくつかの大規模サイトでは、このヒントだけで大きなパフォーマンス向上が得られました。アプリケーションで文字列連結を多用している場合は、このテクニックをあなたの優先順位リストの上位に置いてください。さまざまなサイズの文字列を使用してみて、特定のルーチンに最適のサイズを見つけてください。

中間層キャッシュのために SQL Server を使用していますか

中間層で頻繁に読み取られるが、めったに更新されないデータをキャッシュする必要がある場合は、カスタム ソリューションではなく SQL Server を使用してください。SQL Server は中間層キャッシングについて高いパフォーマンスを備えています。詳細については、「Middle-Tier High-Speed Data Caching Involving COM/MTS and COM+」を参照してください。

必要のないときにトランザクションを使用していませんか

トランザクションはサービスを提供します。そして、そのサービスがパフォーマンスの低下をもたらすことがあります。メソッドが実際にトランザクションを必要としているかどうかを見直してください。たとえば、データ読み取りのためにブラウザ クライアントに渡すレコードセットを取り出す場合は、トランザクションは必要ありません。データを個別のコンポーネントに読み込む操作を、更新を実行する操作から選別することによって、トランザクションが必要なコンポーネントかどうかを柔軟に判断できます。以下の記事には、独自のコンポーネントを選別する際のガイドラインとして役立つ応用パターンが説明されています。

  • 「FMStocks Application: Start Here」

それぞれのメソッドで SetComplete/SetAbort を呼び出していますか

Microsoft Transaction Server (MTS) コンポーネントのそれぞれのメソッドで SetComplete および SetAbort を呼び出すと、リソースが早期に解放され、コンポーネントがトランザクションのスコープ外で生き残るおそれがなくなります。Windows 2000 では、COM+ に [このメソッドが返ったときに、自動的にこのオブジェクトを非アクティブ化する] という設定があり、同様のコードを実行します。この設定は、[コンポーネント サービス] コンソールを使ってメソッド単位で有効にできます。

screen shot

これによるパフォーマンス向上は大規模サイトの方が大きいですが、サイトの規模に関係なく望ましい形です。

子の MTS コンポーネントを CreateInstance で作成していますか

Windows NT 4.0 では、子の MTS コンポーネントを作成するには CreateInstance を使用してください。MTS 以外のコンポーネントを作成するには、 CreateObject または New (コンポーネントが同じ Visual Basic プロジェクトでない場合) を使用します。その他の組み合わせでは、不必要なコードのパスとチェックが発生します。詳細については、Ted Pattison の記事「Creating Objects Properly in an MTS App」を参照してください。

Windows 2000 では、オブジェクトを作成する際にこのようにテクニックを使い分ける必要はなく、CreateObject だけを使用してください (Q250865 "INFO: CreateObject and CreateInstance Have the Same Effect in COM+" Non-MSDN Online link を参照してください)。

Server パッケージのコンポーネントですか、それとも Library パッケージのコンポーネントですか

Library パッケージは呼び出し側のプロセスで実行されるのに対して、Server パッケージのコンポーネントは新しいプロセスで実行されます。このため、Library パッケージには、Server パッケージのようなプロセス間のパフォーマンス低下はありません。一般にお勧めできるのは、Web アプリケーションを別プロセスで実行することですが、プロセス分離とパフォーマンス向上を両立させるためには、Library パッケージのコンポーネントを使用することです。リモートの MTS/COM+ コンポーネントを呼び出すときのように、Server パッケージを使用する必要がある状況では、プロセス間のオーバーヘッドを最小化する措置を講じてください。

プロセス間移動を効率的に行っていますか

分散アプリケーションのパフォーマンスを高めるには、マーシャリングのオーバーヘッドを最小化し、ネットワーク呼び出しを減らすことが鍵です。レイト バインドの原因となる GetIdsOfNames の呼び出しをなくして、コンポーネントの事前バインドを使用することで、コストのかかるネットワーク ラウンドトリップを最小化してください。一群のプロパティを個別に設定するのではなく、メソッド呼び出しの引数にパラメータをバンドルすることによって、ネットワーク ラウンドトリップをさらに削減することができます。パラメータを参照渡し (ByRef) ではなく値渡し (ByVal) すれば、マーシャリングのオーバーヘッドを最小化できます。

リモート コンポーネントを使用していますか

多くの開発者は、リモート コンポーネントを呼び出さなければならない状況を経験しています。そのような場合には、効率的なプロセス間移動のためのルールのすべてが適用されます。その他にお勧めできるのは、中間パッケージの使用です (Q159311 "Instantiating Remote Components in MTS and IIS" Non-MSDN Online link を参照)。中間パッケージを使用してリモート コンポーネントを呼び出すと、セキュリティの複雑化を避けることができ、また、事前バインドを使用することができます。

クライアント マシンとサーバー マシンが同じ DCOM プロトコルを使用していますか

リモート コンポーネントのアクティブ化の遅延の一般的な原因は、クライアント マシンとサーバー マシンの DCOM プロトコル リストが異なることにあります。それぞれのマシンで DCOMCNFG.EXE を使用して、プロトコル シーケンスを一致させてください。たとえば、両方のマシンが TCP/IP を使用している場合は、TCP/IP を両方のマシンのリストの先頭に移動します。

DCOM プロトコル リストを変更するときには、いくつかのガイドラインが適用されます。

  • 可能な場合は、TCP/IP を先頭に移動します。
  • 不要なプロトコルを削除します。
  • プロトコル リストに変更を加えた場合は、再起動が必要です。

screen shot

リモート コンポーネントから ASP 組み込みオブジェクトを使用していますか

これは、やめてください。複数のマシン間で ASP 組み込みオブジェクト (Request、Response など) をマーシャルする方法がわかっている場合でも、パフォーマンス低下の方が利点を上回ります。

Visual Basic を使用していますか

正しいバージョンを使用し、正しい設定を使用し、以下の設計ガイドラインに従えば、Visual Basic は優れたパフォーマンスを発揮します。

screen shot

MFC を使用していますか

Active Template Library (ATL) コンポーネントは Microsoft Foundation Classes (MFC) より軽量であり、サーバー コンポーネントに適しています。MFC コードはサーバーには重く、状態管理に予期しない直列化をもたらすことがあります。また、Both としてマークされた、FTM を収集するコンポーネントを作成することができません。MFC は、ページ スコープに限定される STA オブジェクトだけを生成します。

Java を使用していますか

https://www.microsoft.com/java/ Non-MSDN Online link から最新の仮想マシンを入手してください。また、Q232368 "PRB: Java Threads Blocking when Accessing COM Objects" Non-MSDN Online link を読んでください。

非同期で実行できるものを待っていませんか

あなたの ASP アプリケーションが時間のかかるデータベース呼び出しを行う場合や、ほかのコンポーネントからイベントが発生するのを待っているコンポーネントを呼び出す場合には、MSMQ などのキューイング メカニズムによる非同期呼び出しの使用を考慮してみてください。MSMQ については、以下を参照してください。

中間層の大きなデータセットをループしていますか

このような大きなデータや複雑なデータの操作は、できればストアド プロシージャに入れてください。

データ アクセスのパフォーマンス

データベースでインデックスを使用していますか

インデックスは、アプリケーションのパフォーマンスに直接影響を与えます。できの悪いインデックスはアプリケーションを這うように遅くし、よくできたインデックスはアプリケーションのパフォーマンスの最適化に役立ちます。インデックスのチューニングについては、「Top Ten Tips: Accessing SQL Through ADO and ASP」 または SQL Books Online を参照してください。

動的な SQL ではなくストアド プロシージャを呼び出していますか

ストアド プロシージャを使用すると、データベースは SQL ステートメントを何度も再コンパイルする必要がなくなります。ストアド プロシージャまたはパラメータ化された SQL 文字列を使用してください。

必要なデータだけを返していますか

SELECT ステートメントを見直して、必要な列と必要な行だけを返しているかどうかを確認してください。多くのレコードを返す可能性があるクエリについては、レコードセットによるページングを考慮してください。詳細については、以下の記事を参照してください。

DAO または RDO を使用していますか

Remote Data Objects (RDO) および Data Access Objects (DAO) は、単一クライアント アプリケーション プロセス向けであり、Web ではテストされていません。ADO は Web での使用を目的として設計され、テストされています。

どのバージョンの MDAC を使用していますか

MDAC の更新版では、信頼性とパフォーマンスが向上しています。MDAC version 2.1 Service Pack 2 以上を使用してください。最も安定性が高く、最も徹底的にテストされている MDAC 2.5 をお勧めします。使用しているバージョンがわからない場合は、 https://msdn2.microsoft.com/en-us/data/default.aspx Non-MSDN Online linkから Component Checker ツールを入手することができます。

MDAC のベスト プラクティスに従っていますか

Improve MDAC Application Performance」を参照してください。

接続プーリングを使っていますか

プーリングにより、データベースへの接続を再利用することができます。ODBC 接続プーリングは、MDAC 2.0 ではデフォルトで有効になっています。MDAC 2.1 以上では、OleDb セッション プーリングがデフォルトです。プーリングが機能するためには、接続文字列内のユーザー名、パスワード、およびリソースが一致している必要があります (バイト単位で比較されます)。

プーリングの詳細については、以下の記事を参照してください。

ADO 接続をセッション スコープまたはアプリケーション スコープに格納していますか

このようにすると、接続プーリングが無駄になり、リソースの競合が生じます。接続はページ スコープで作成するか、接続を必要とする関数内で作成してください。また、接続を nothing に設定して、プールに戻してください。

Recordset および Connection 変数を明示的にクローズしていますか

レコードセットを再利用する場合は、クローズしておく必要があります (しかし、レコードセットの再利用はお勧めできません)。Connection 変数をプールに解放できるようになったらすぐにクローズしてください。そうすれば、再利用のためにプールできます。オブジェクト変数を明示的にクローズするのは、常に望ましいことです。

Recordset および Command 変数を再利用していますか

既存のものを再利用するのではなく、新しい Recordset および Command 変数を作成してください。これは必ずしもアプリケーションのパフォーマンスを高めるわけではありませんが、アプリケーションの信頼性を高め、保守を容易にします。詳細については、Q197449 "PRB: Problems Reusing ADO Command Object on Multiple Recordsets" Non-MSDN Online link を参照してください。

レコードセットを切断していますか

レコードセットを切断すると、Connection オブジェクトは解放されてプールに戻るので、Connection をクローズして、すぐに再利用することができます。

ジョブに応じた正しいカーソルとロック タイプを使用していますか

データへのシングル パスが必要なときには、"Firehose" (前方のみ、読み取り専用) カーソルを使用してください。Firehose カーソルは、ADO のデフォルトのカーソルであり、最速のパフォーマンスと最小のオーバーヘッドを提供します。カーソルとロック タイプの詳細については、ADO のドキュメントを参照してください。

DSN レス接続を使用していますか

一般に、DSN レス接続はシステム DSN (Data Source Name) より高速であり、システム DSN はファイル DSN より高速です。

Access を使用していますか

Microsoft Access はファイルベースのデータベースなので、IIS 下の同時並行ユーザーではパフォーマンスを発揮できません。

SQL Server を使用していますか

SQL Server 7.0 を使用してください。SQL Server 7.0 は、以前のバージョンの SQL Server より優れており、行レベル ロックなどパフォーマンス上の利点を備えています。SQL スケールについて聞いたことがあると思いますが、念のために http://www.tpc.org/ Non-MS linkhttps://research.microsoft.com/scalable/ Non-MSDN Online link にある Jim Gray の記事を参照してください。

ネットワーク ライブラリに TCP/IP を使用していますか

パフォーマンスとスケーラビリティのために、ネットワーク ライブラリには TCP/IP を使用してください。

OLEDB SQL プロバイダを使用していますか

パフォーマンスと信頼性の点で、OLEDB の ODBC プロバイダ MSDASQL よりも SQL プロバイダ SQLOLEDB をお勧めします。

Oracle を使用していますか

Oracle のパフォーマンスは、正しい MDAC ビットと正しい Oracle クライアント パッチの組み合わせを使用しているかどうかによって大きく左右されます。Oracle を使用する場合は、以下の記事を参照してください。

  • "Microsoft OLE DB Provider for Oracle: Tips, Tricks, and Traps"
  • "Fitch & Mather Stocks: Data Access Layer for Oracle 8"

Oracle と MTS を使用する場合は、以下の記事を参照してください。

レポートとトランザクションに同じデータベースを使用していますか

大規模な Web サイトの多くは、パフォーマンス向上のための効率的な手段として、読み取り専用データとトランザクション用データを個別のデータベースで保持しています。この方法には、レポートのために最適化されたデータベース スキーマを設計できるという利点もあります。

IIS の設定

ASP デバッグが有効になっていませんか

ISM を確認してください。ASP のデバッグが有効になっている場合、アプリケーションは 1 つの実行スレッドにロックされます。Q216580 "PRB: Blocking/Serialization When Using InProc Component (DLL) from ASP." Non-MSDN Online link を参照してください。

screen shot

ASP は十分なスレッド/スクリプト エンジンを持つように構成されていますか

"The Art and Science of Web Server Tuning with Internet Information Services 5.0" Non-MSDN Online link と "Navigating the Maze of Settings for Web Server Performance Optimization" Non-MSDN Online link をご覧ください。

SSL を使用していますか

Secure Sockets Layer (SSL) は、バンド幅と CPU 使用率の点でコストが高くつきます。SSL を使用するとしたら、それはセキュリティ上必要だからです。一番よいのは、SSL の使用を必要な場所だけに制限して、ページをシンプルに保つことです。 **

ストレス テスト

パフォーマンス=スケーラビリティというのは、よくある誤解です。ASP のパフォーマンスとは、ページがどのくらい速く表示されるかを意味します。スケーラビリティは、負荷が増したときに、どの程度パフォーマンスが低下するかによって計られます。たとえば、あなたの ASP アプリケーションは、ユーザーが 10 人のときにはパフォーマンスを発揮するかもしれませんが、1000 人のユーザーに対応できるスケーラビリティは備えていないかもしれません。パフォーマンスが受け入れられない程度まで低下するかもしれないからです。あなたの ASP アプリケーションのパフォーマンスとスケーラビリティを測定するには、ストレス テストを使用してください。Windows DNA アプリケーションのスケーラビリティについては、「 Microsoft Windows DNA プラットフォームを使用した Web サイト構築」を参照してください。

どの程度のパフォーマンスを期待していますか

パフォーマンスは、サーバーが 1 秒間に処理できる ASP 要求の数で測定されます。ASP のパフォーマンス カウンタ ASP Requests Per Second を使用して、測定するベンチマークを設定することができます。

ブラウザでストレス テストを実行しようとしていませんか

ブラウザでストレス テストを実行しても、正しい結果が得られないことがあります。すでに述べたように、ASP は同じセッションからの同時並行の要求を直列化します。たとえば、Cookie が有効になっているマシンからサーバーにアクセスした場合、それらの要求は直列化されます。Web Application Stress ツール (WAS -- 旧称 Homer) を使用してください。WAS の説明については、「I Can't Stress It Enough ASP アプリケーションのロード テスト」を参照してください。

エンド ツー エンドのテストを実行しましたか

データベース、コンポーネント、および ASP 層を個別にストレス テストすることは、重要であり、適切なことですが、アプリケーションの本当のボトルネックがわかるのは、エンド ツー エンドのテストによってです。

まとめ

ASP アプリケーションのパフォーマンスを評価するということは、いくつかの点を見ることを意味します。アプリケーションをさまざまな層に分けることによって、パフォーマンス問題を分析するためのフレームワークを作ることができます。多くのガイドラインと推奨がありますが、アプリケーションのストレス テストと客観的な判断に優るものはありません。

J.D. Meier は米国東海岸で生まれて育ちました。Horace Greeley の助言に従って、MTS および ASP 技術を含むサーバー側コンポーネントと Windows DNA アプリケーションを専門とするデベロッパ サポート エンジニアとして働いています。