다음을 통해 공유


SqlClient에서의 성능 카운터

적용 대상: .NET Framework 지원되지 않습니다. .NET Core 지원되지 않습니다. .NET Standard

ADO.NET 다운로드

Microsoft.Data.SqlClient 성능 카운터를 사용하여 애플리케이션 상태와 애플리케이션에서 사용하는 연결 리소스를 모니터링할 수 있습니다. 성능 카운터는 Windows 성능 카운터를 사용하여 모니터링하거나 PerformanceCounter 네임스페이스의 System.Diagnostics 클래스를 사용하여 프로그래밍 방식으로 액세스할 수 있습니다.

사용 가능한 성능 카운터

현재 다음 표에 설명된 대로 14가지 성능 카운터를 Microsoft.Data.SqlClient에 사용할 수 있습니다.

성능 카운터 설명
HardConnectsPerSecond 데이터베이스 서버에 대한 초당 연결 수입니다.
HardDisconnectsPerSecond 데이터베이스 서버에 대한 초당 끊긴 연결 수입니다.
NumberOfActiveConnectionPoolGroups 활성화되어 있는 고유 연결 풀 그룹 수입니다. 이 카운터는 AppDomain에 있는 고유 연결 문자열 수에 의해 제어됩니다.
NumberOfActiveConnectionPools 연결 풀의 총 수입니다.
NumberOfActiveConnections 현재 사용 중인 활성 연결 수입니다. 참고: 이 성능 카운터는 기본적으로 활성화되지 않습니다. 이 성능 카운터를 활성화하려면 기본적으로 활성화되지 않은 카운터 활성화를 참조하세요.
NumberOfFreeConnections 연결 풀에서 사용할 수 있는 연결 수입니다. 참고: 이 성능 카운터는 기본적으로 활성화되지 않습니다. 이 성능 카운터를 활성화하려면 기본적으로 활성화되지 않은 카운터 활성화를 참조하세요.
NumberOfInactiveConnectionPoolGroups 정리하기로 표시된 고유 연결 풀 그룹 수입니다. 이 카운터는 AppDomain에 있는 고유 연결 문자열 수에 의해 제어됩니다.
NumberOfInactiveConnectionPools 최근 활성화되지 않았고 삭제 대기 중인 비활성 연결 풀 수입니다.
NumberOfNonPooledConnections 풀링되지 않은 활성 연결 수입니다.
NumberOfPooledConnections 연결 풀링 인프라에서 관리되는 활성 연결 수입니다.
NumberOfReclaimedConnections 애플리케이션에서 Close 또는 Dispose를 호출하지 않은 가비지 수집에서 회수된 연결 수입니다. 참고 명시적으로 연결을 닫거나 삭제하지 않으면 성능이 저하됩니다.
NumberOfStasisConnections 현재 작업 완료 대기 중이어서 사용자 애플리케이션에서 사용할 수 없는 연결 수입니다.
SoftConnectsPerSecond 연결 풀에서 풀링되는 활성 연결 수입니다. 참고: 이 성능 카운터는 기본적으로 활성화되지 않습니다. 이 성능 카운터를 활성화하려면 기본적으로 활성화되지 않은 카운터 활성화를 참조하세요.
SoftDisconnectsPerSecond 연결 풀로 반환되는 활성 연결 수입니다. 참고: 이 성능 카운터는 기본적으로 활성화되지 않습니다. 이 성능 카운터를 활성화하려면 기본적으로 활성화되지 않은 카운터 활성화를 참조하세요.

기본적으로 활성화되지 않은 카운터 활성화

NumberOfFreeConnections, NumberOfActiveConnections, SoftDisconnectsPerSecondSoftConnectsPerSecond 성능 카운터는 기본적으로 비활성화되어 있습니다. 다음 정보를 애플리케이션의 구성 파일에 추가하여 이러한 성능 카운터를 활성화할 수 있습니다.

<system.diagnostics>  
  <switches>  
    <add name="ConnectionPoolPerformanceCounterDetail" value="4"/>  
    <!-- A value of 4 corresponds to System.Diagnostics.TraceLevel.Verbose -->
  </switches>  
</system.diagnostics>  

성능 카운터 값 검색

다음 콘솔 애플리케이션에서는 사용자 애플리케이션에서 성능 카운터 값을 검색하는 방법을 보여 줍니다. 모든 SQL Server용 Microsoft SqlClient 데이터 공급자 성능 카운터에서 반환되는 정보에 대해 연결이 열려 있고 활성화되어야 합니다.

참고 항목

이 예제에서는 AdventureWorks 데이터베이스 샘플을 사용합니다. 이 샘플 코드에 제공된 연결 문자열에서는 데이터베이스가 로컬 컴퓨터에 설치되어 있고 사용 가능하며 연결 문자열에 제공된 문자열과 일치하는 로그인을 만들었다고 가정합니다. Windows 인증만 허용하는 기본 보안 설정을 사용하여 서버를 구성하는 경우 SQL Server 로그인을 활성화해야 할 수도 있습니다. 사용자 환경에 맞게 연결 문자열을 수정합니다.

예시

using System;
using Microsoft.Data.SqlClient;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace PerformanceCounterTest
{
    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=.;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=.;User Id=<myUserID>;Password=<myPassword>;" +
              "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=.;" +
              "User Id=<myUserID>;Password=<myPassword>;";
        }
    }
}

참고 항목