ADO.NET でのパフォーマンス カウンターPerformance Counters in ADO.NET

ADO.NET 2.0 では、System.Data.SqlClientSystem.Data.OracleClient の両方をサポートする新しいパフォーマンス カウンターが導入されました。ADO.NET 2.0 introduced expanded support for performance counters that includes support for both System.Data.SqlClient and System.Data.OracleClient. 以前のバージョンの ADO.NET で利用されていた System.Data.SqlClient のパフォーマンス カウンターは非推奨とされ、このトピックで説明する新しいパフォーマンス カウンターに置き換えられました。The System.Data.SqlClient performance counters available in previous versions of ADO.NET have been deprecated and replaced with the new performance counters discussed in this topic. ADO.NET のパフォーマンス カウンターを使用することで、アプリケーションやそれによって使用される接続リソースのステータスを監視できます。You can use ADO.NET performance counters to monitor the status of your application and the connection resources that it uses. パフォーマンス カウンターは、Windows パフォーマンス モニターを使って監視できるほか、PerformanceCounter 名前空間の System.Diagnostics クラスを使用することでプログラムから監視することもできます。Performance counters can be monitored by using Windows Performance Monitor or can be accessed programmatically using the PerformanceCounter class in the System.Diagnostics namespace.

利用可能なパフォーマンス カウンターAvailable Performance Counters

次の表に示したように、System.Data.SqlClient および System.Data.OracleClient には現在、14 種類のパフォーマンス カウンターが存在します。Currently there are 14 different performance counters available for System.Data.SqlClient and System.Data.OracleClient as described in the following table. 個々のカウンターの名前は、Microsoft .NET Framework の地域別バージョン全体でローカライズされているわけではないことに注意してください。Note that the names for the individual counters are not localized across regional versions of the Microsoft .NET Framework.

パフォーマンス カウンターPerformance counter 説明Description
HardConnectsPerSecond データベース サーバーに対する 1 秒あたりの接続数。The number of connections per second that are being made to a database server.
HardDisconnectsPerSecond データベース サーバーに対する 1 秒あたりの切断数。The number of disconnects per second that are being made to a database server.
NumberOfActiveConnectionPoolGroups アクティブな一意の接続プール グループの数。The number of unique connection pool groups that are active. このカウンターは、AppDomain に見つかった一意の接続文字列数によって制御されます。This counter is controlled by the number of unique connection strings that are found in the AppDomain.
NumberOfActiveConnectionPools 接続プールの合計数。The total number of connection pools.
NumberOfActiveConnections 現在使用中のアクティブな接続の数。The number of active connections that are currently in use. 注: 既定では、このパフォーマンス カウンターが無効にされています。Note: This performance counter is not enabled by default. このパフォーマンス カウンターを有効にするのを参照してください。既定ではオフ カウンターのアクティブ化するします。To enable this performance counter, see Activating Off-By-Default Counters.
NumberOfFreeConnections 接続プール内の利用可能な接続数。The number of connections available for use in the connection pools. 注: 既定では、このパフォーマンス カウンターが無効にされています。Note: This performance counter is not enabled by default. このパフォーマンス カウンターを有効にするのを参照してください。既定ではオフ カウンターのアクティブ化するします。To enable this performance counter, see Activating Off-By-Default Counters.
NumberOfInactiveConnectionPoolGroups 排除対象としてマークされた一意の接続プール グループの数。The number of unique connection pool groups that are marked for pruning. このカウンターは、AppDomain に見つかった一意の接続文字列数によって制御されます。This counter is controlled by the number of unique connection strings that are found in the AppDomain.
NumberOfInactiveConnectionPools 最近のアクティビティが存在せず、破棄待ち状態となっている、アクティブでない接続プールの数。The number of inactive connection pools that have not had any recent activity and are waiting to be disposed.
NumberOfNonPooledConnections プールされていないアクティブな接続の数。The number of active connections that are not pooled.
NumberOfPooledConnections 接続プール インフラストラクチャによって管理されているアクティブな接続の数。The number of active connections that are being managed by the connection pooling infrastructure.
NumberOfReclaimedConnections アプリケーションによって CloseDispose も呼び出されなかった場合に、ガベージ コレクションによって回収された接続の数。The number of connections that have been reclaimed through garbage collection where Close or Dispose was not called by the application. 接続を明示的に閉じるか破棄しないと、パフォーマンスが低下します。Not explicitly closing or disposing connections hurts performance.
NumberOfStasisConnections 現在アクションの完了を待っている (そのためにアプリケーションからは使用できない) 接続の数。The number of connections currently awaiting completion of an action and which are therefore unavailable for use by your application.
SoftConnectsPerSecond 接続プールからプルされているアクティブな接続の数。The number of active connections being pulled from the connection pool. 注: 既定では、このパフォーマンス カウンターが無効にされています。Note: This performance counter is not enabled by default. このパフォーマンス カウンターを有効にするのを参照してください。既定ではオフ カウンターのアクティブ化するします。To enable this performance counter, see Activating Off-By-Default Counters.
SoftDisconnectsPerSecond 接続プールに戻されているアクティブな接続の数。The number of active connections that are being returned to the connection pool. 注: 既定では、このパフォーマンス カウンターが無効にされています。Note: This performance counter is not enabled by default. このパフォーマンス カウンターを有効にするのを参照してください。既定ではオフ カウンターのアクティブ化するします。To enable this performance counter, see Activating Off-By-Default Counters.

接続プール グループと接続プールConnection Pool Groups and Connection Pools

Windows 認証 (統合セキュリティ) を使用している場合、NumberOfActiveConnectionPoolGroupsNumberOfActiveConnectionPools の両方のパフォーマンス カウンターを監視する必要があります。When using Windows Authentication (integrated security), you must monitor both the NumberOfActiveConnectionPoolGroups and NumberOfActiveConnectionPools performance counters. なぜなら、接続プール グループは接続文字列単位でマップされるためです。The reason is that connection pool groups map to unique connection strings. 統合セキュリティを使用した場合、接続文字列にマップされた接続プールの他に、個々の Windows ID 用に別々のプールが作成されます。When integrated security is used, connection pools map to connection strings and additionally create separate pools for individual Windows identities. たとえば、同じ AppDomain に属する Fred と Julie が、どちらも "Data Source=MySqlServer;Integrated Security=true" という接続文字列を使用した場合、その接続文字列に対応した接続プール グループが作成され、それに加えて、2 つのプール (Fred 用と Julie 用) が作成されます。For example, if Fred and Julie, each within the same AppDomain, both use the connection string "Data Source=MySqlServer;Integrated Security=true", a connection pool group is created for the connection string, and two additional pools are created, one for Fred and one for Julie. John とマーサは、接続文字列を使用して、同一の SQL Server ログインの場合"Data Source=MySqlServer;User Id=lowPrivUser;Password=Strong?Password"の 1 つのプールのみが作成し、 lowPrivUserの id。If John and Martha use a connection string with an identical SQL Server login, "Data Source=MySqlServer;User Id=lowPrivUser;Password=Strong?Password", then only a single pool is created for the lowPrivUser identity.

既定ではオフになっているカウンターのアクティブ化Activating Off-By-Default Counters

NumberOfFreeConnectionsNumberOfActiveConnectionsSoftDisconnectsPerSecondSoftConnectsPerSecond の各パフォーマンス カウンターは、既定ではオフになっています。The performance counters NumberOfFreeConnections, NumberOfActiveConnections, SoftDisconnectsPerSecond, and SoftConnectsPerSecond are off by default. 有効にするには、アプリケーションの構成ファイルに次の情報を追加します。Add the following information to the application's configuration file to enable them:

<system.diagnostics>  
  <switches>  
    <add name="ConnectionPoolPerformanceCounterDetail"  
         value="4"/>  
  </switches>  
</system.diagnostics>  

パフォーマンス カウンターの値の取得Retrieving Performance Counter Values

次のコンソール アプリケーションは、アプリケーションでパフォーマンス カウンターの値を取得する方法を示しています。The following console application shows how to retrieve performance counter values in your application. すべての ADO.NET パフォーマンス カウンターの情報を取得できるように、接続を開いてアクティブにする必要があります。Connections must be open and active for information to be returned for all of the ADO.NET performance counters.

注意

この例は、サンプルを使用してAdventureWorks SQL Server に含まれているデータベース。This example uses the sample AdventureWorks database included with SQL Server. サンプル コードの接続文字列は、データベースがローカル コンピューターにインストールされていること、SqlExpress というインスタンス名で実行されていること、接続文字列に指定された情報と一致する SQL Server ログインが作成済みであることを想定しています。The connection strings provided in the sample code assume that the database is installed and available on the local computer with an instance name of SqlExpress, and that you have created SQL Server logins that match those supplied in the connection strings. 既定のセキュリティ設定を使用するようにサーバーが構成されている場合、そのままでは Windows 認証しか許可されないため、SQL Server ログインを有効にする必要があります。You may need to enable SQL Server logins if your server is configured using the default security settings which allow only Windows Authentication. 接続文字列は環境に合わせて変更してください。Modify the connection strings as necessary to suit your environment.

Example

Option Explicit On  
Option Strict On  
  
Imports System.Data.SqlClient  
Imports System.Diagnostics  
Imports System.Runtime.InteropServices  
  
Class Program  
  
    Private PerfCounters(9) As PerformanceCounter  
    Private connection As SqlConnection = New SqlConnection  
  
    Public Shared Sub Main()  
        Dim prog As Program = New Program  
        ' Open a connection and create the performance counters.   
        prog.connection.ConnectionString = _  
           GetIntegratedSecurityConnectionString()  
        prog.SetUpPerformanceCounters()  
        Console.WriteLine("Available Performance Counters:")  
  
        ' Create the connections and display the results.  
        prog.CreateConnections()  
        Console.WriteLine("Press Enter to finish.")  
        Console.ReadLine()  
    End Sub  
  
    Private Sub CreateConnections()  
        ' List the Performance counters.  
        WritePerformanceCounters()  
  
        ' Create 4 connections and display counter information.  
        Dim connection1 As SqlConnection = New SqlConnection( _  
           GetIntegratedSecurityConnectionString)  
        connection1.Open()  
        Console.WriteLine("Opened the 1st Connection:")  
        WritePerformanceCounters()  
  
        Dim connection2 As SqlConnection = New SqlConnection( _  
           GetSqlConnectionStringDifferent)  
        connection2.Open()  
        Console.WriteLine("Opened the 2nd Connection:")  
        WritePerformanceCounters()  
  
        Console.WriteLine("Opened the 3rd Connection:")  
        Dim connection3 As SqlConnection = New SqlConnection( _  
           GetSqlConnectionString)  
        connection3.Open()  
        WritePerformanceCounters()  
  
        Dim connection4 As SqlConnection = New SqlConnection( _  
           GetSqlConnectionString)  
        connection4.Open()  
        Console.WriteLine("Opened the 4th Connection:")  
        WritePerformanceCounters()  
  
        connection1.Close()  
        Console.WriteLine("Closed the 1st Connection:")  
        WritePerformanceCounters()  
  
        connection2.Close()  
        Console.WriteLine("Closed the 2nd Connection:")  
        WritePerformanceCounters()  
  
        connection3.Close()  
        Console.WriteLine("Closed the 3rd Connection:")  
        WritePerformanceCounters()  
  
        connection4.Close()  
        Console.WriteLine("Closed the 4th Connection:")  
        WritePerformanceCounters()  
    End Sub  
  
    Private Enum ADO_Net_Performance_Counters  
        NumberOfActiveConnectionPools  
        NumberOfReclaimedConnections  
        HardConnectsPerSecond  
        HardDisconnectsPerSecond  
        NumberOfActiveConnectionPoolGroups  
        NumberOfInactiveConnectionPoolGroups  
        NumberOfInactiveConnectionPools  
        NumberOfNonPooledConnections  
        NumberOfPooledConnections  
        NumberOfStasisConnections  
        ' The following performance counters are more expensive to track.  
        ' Enable ConnectionPoolPerformanceCounterDetail in your config file.  
        '     SoftConnectsPerSecond  
        '     SoftDisconnectsPerSecond  
        '     NumberOfActiveConnections  
        '     NumberOfFreeConnections  
    End Enum  
  
    Private Sub SetUpPerformanceCounters()  
        connection.Close()  
        Me.PerfCounters(9) = New PerformanceCounter()  
  
        Dim instanceName As String = GetInstanceName()  
        Dim apc As Type = GetType(ADO_Net_Performance_Counters)  
        Dim i As Integer = 0  
        Dim s As String = ""  
        For Each s In [Enum].GetNames(apc)  
            Me.PerfCounters(i) = New PerformanceCounter()  
            Me.PerfCounters(i).CategoryName = ".NET Data Provider for SqlServer"  
            Me.PerfCounters(i).CounterName = s  
            Me.PerfCounters(i).InstanceName = instanceName  
            i = (i + 1)  
        Next  
    End Sub  
  
    Private Declare Function GetCurrentProcessId Lib "kernel32.dll" () As Integer  
  
    Private Function GetInstanceName() As String  
        'This works for Winforms apps.   
        Dim instanceName As String = _  
           System.Reflection.Assembly.GetEntryAssembly.GetName.Name  
  
        ' Must replace special characters like (, ), #, /, \\   
        Dim instanceName2 As String = _  
           AppDomain.CurrentDomain.FriendlyName.ToString.Replace("(", "[") _  
           .Replace(")", "]").Replace("#", "_").Replace("/", "_").Replace("\\", "_")  
  
        'For ASP.NET applications your instanceName will be your CurrentDomain's   
        'FriendlyName. Replace the line above that sets the instanceName with this:   
        'instanceName = AppDomain.CurrentDomain.FriendlyName.ToString.Replace("(", "[") _  
        '    .Replace(")", "]").Replace("#", "_").Replace("/", "_").Replace("\\", "_")  
  
        Dim pid As String = GetCurrentProcessId.ToString  
        instanceName = (instanceName + ("[" & (pid & "]")))  
        Console.WriteLine("Instance Name: {0}", instanceName)  
        Console.WriteLine("---------------------------")  
        Return instanceName  
    End Function  
  
    Private Sub WritePerformanceCounters()  
        Console.WriteLine("---------------------------")  
        For Each p As PerformanceCounter In Me.PerfCounters  
            Console.WriteLine("{0} = {1}", p.CounterName, p.NextValue)  
        Next  
        Console.WriteLine("---------------------------")  
    End Sub  
  
    Private Shared Function GetIntegratedSecurityConnectionString() As String  
        ' To avoid storing the connection string in your code,   
        ' you can retrieve it from a configuration file.   
        Return ("Data Source=.\SqlExpress;Integrated Security=True;" &   
          "Initial Catalog=AdventureWorks")  
    End Function  
  
    Private Shared Function GetSqlConnectionString() As String  
        ' To avoid storing the connection string in your code,   
        ' you can retrieve it from a configuration file.   
        Return ("Data Source=.\SqlExpress;User Id=LowPriv;Password=Data!05;" &   
          "Initial Catalog=AdventureWorks")  
    End Function  
  
    Private Shared Function GetSqlConnectionStringDifferent() As String  
        ' To avoid storing the connection string in your code,   
        ' you can retrieve it from a configuration file.   
        Return ("Initial Catalog=AdventureWorks;Data Source=.\SqlExpress;" & _  
          "User Id=LowPriv;Password=Data!05;")  
    End Function  
End Class  
using System;  
using System.Data.SqlClient;  
using System.Diagnostics;  
using System.Runtime.InteropServices;  
  
class Program  
{  
    PerformanceCounter[] PerfCounters = new PerformanceCounter[10];  
    SqlConnection connection = new SqlConnection();  
  
    static void Main()  
    {  
        Program prog = new Program();  
        // Open a connection and create the performance counters.  
        prog.connection.ConnectionString =  
           GetIntegratedSecurityConnectionString();  
        prog.SetUpPerformanceCounters();  
        Console.WriteLine("Available Performance Counters:");  
  
        // Create the connections and display the results.  
        prog.CreateConnections();  
        Console.WriteLine("Press Enter to finish.");  
        Console.ReadLine();  
    }  
  
    private void CreateConnections()  
    {  
        // List the Performance counters.  
        WritePerformanceCounters();  
  
        // Create 4 connections and display counter information.  
        SqlConnection connection1 = new SqlConnection(  
              GetIntegratedSecurityConnectionString());  
        connection1.Open();  
        Console.WriteLine("Opened the 1st Connection:");  
        WritePerformanceCounters();  
  
        SqlConnection connection2 = new SqlConnection(  
              GetSqlConnectionStringDifferent());  
        connection2.Open();  
        Console.WriteLine("Opened the 2nd Connection:");  
        WritePerformanceCounters();  
  
        SqlConnection connection3 = new SqlConnection(  
              GetSqlConnectionString());  
        connection3.Open();  
        Console.WriteLine("Opened the 3rd Connection:");  
        WritePerformanceCounters();  
  
        SqlConnection connection4 = new SqlConnection(  
              GetSqlConnectionString());  
        connection4.Open();  
        Console.WriteLine("Opened the 4th Connection:");  
        WritePerformanceCounters();  
  
        connection1.Close();  
        Console.WriteLine("Closed the 1st Connection:");  
        WritePerformanceCounters();  
  
        connection2.Close();  
        Console.WriteLine("Closed the 2nd Connection:");  
        WritePerformanceCounters();  
  
        connection3.Close();  
        Console.WriteLine("Closed the 3rd Connection:");  
        WritePerformanceCounters();  
  
        connection4.Close();  
        Console.WriteLine("Closed the 4th Connection:");  
        WritePerformanceCounters();  
    }  
  
    private enum ADO_Net_Performance_Counters  
    {  
        NumberOfActiveConnectionPools,  
        NumberOfReclaimedConnections,  
        HardConnectsPerSecond,  
        HardDisconnectsPerSecond,  
        NumberOfActiveConnectionPoolGroups,  
        NumberOfInactiveConnectionPoolGroups,  
        NumberOfInactiveConnectionPools,  
        NumberOfNonPooledConnections,  
        NumberOfPooledConnections,  
        NumberOfStasisConnections  
        // The following performance counters are more expensive to track.  
        // Enable ConnectionPoolPerformanceCounterDetail in your config file.  
        //     SoftConnectsPerSecond  
        //     SoftDisconnectsPerSecond  
        //     NumberOfActiveConnections  
        //     NumberOfFreeConnections  
    }  
  
    private void SetUpPerformanceCounters()  
    {  
        connection.Close();  
        this.PerfCounters = new PerformanceCounter[10];  
        string instanceName = GetInstanceName();  
        Type apc = typeof(ADO_Net_Performance_Counters);  
        int i = 0;  
        foreach (string s in Enum.GetNames(apc))  
        {  
            this.PerfCounters[i] = new PerformanceCounter();  
            this.PerfCounters[i].CategoryName = ".NET Data Provider for SqlServer";  
            this.PerfCounters[i].CounterName = s;  
            this.PerfCounters[i].InstanceName = instanceName;  
            i++;  
        }  
    }  
  
    [DllImport("kernel32.dll", SetLastError = true)]  
    static extern int GetCurrentProcessId();  
  
    private string GetInstanceName()  
    {  
        //This works for Winforms apps.  
        string instanceName =  
            System.Reflection.Assembly.GetEntryAssembly().GetName().Name;  
  
        // Must replace special characters like (, ), #, /, \\  
        string instanceName2 =  
            AppDomain.CurrentDomain.FriendlyName.ToString().Replace('(', '[')  
            .Replace(')', ']').Replace('#', '_').Replace('/', '_').Replace('\\', '_');  
  
        // For ASP.NET applications your instanceName will be your CurrentDomain's   
        // FriendlyName. Replace the line above that sets the instanceName with this:  
        // instanceName = AppDomain.CurrentDomain.FriendlyName.ToString().Replace('(','[')  
        // .Replace(')',']').Replace('#','_').Replace('/','_').Replace('\\','_');  
  
        string pid = GetCurrentProcessId().ToString();  
        instanceName = instanceName + "[" + pid + "]";  
        Console.WriteLine("Instance Name: {0}", instanceName);  
        Console.WriteLine("---------------------------");  
        return instanceName;  
    }  
  
    private void WritePerformanceCounters()  
    {  
        Console.WriteLine("---------------------------");  
        foreach (PerformanceCounter p in this.PerfCounters)  
        {  
            Console.WriteLine("{0} = {1}", p.CounterName, p.NextValue());  
        }  
        Console.WriteLine("---------------------------");  
    }  
  
    private static string GetIntegratedSecurityConnectionString()  
    {  
        // To avoid storing the connection string in your code,  
        // you can retrieve it from a configuration file.  
        return @"Data Source=.\SqlExpress;Integrated Security=True;" +  
          "Initial Catalog=AdventureWorks";  
    }  
    private static string GetSqlConnectionString()  
    {  
        // To avoid storing the connection string in your code,  
        // you can retrieve it from a configuration file.  
        return @"Data Source=.\SqlExpress;User Id=LowPriv;Password=Data!05;" +  
          "Initial Catalog=AdventureWorks";  
    }  
  
    private static string GetSqlConnectionStringDifferent()  
    {  
        // To avoid storing the connection string in your code,  
        // you can retrieve it from a configuration file.  
        return @"Initial Catalog=AdventureWorks;Data Source=.\SqlExpress;" +  
          "User Id=LowPriv;Password=Data!05;";  
    }  
}  

関連項目See also