Счетчики производительности в SqlClient

Область применения: .NET Framework Not supported. .NET Core Not supported. .NET Standard

Скачать ADO.NET

Счетчики производительности Microsoft.Data.SqlClient можно использовать для мониторинга состояния приложения и используемых им ресурсов подключения. Показания счетчиков производительности можно отслеживать с помощью системного монитора Windows или получить к ним доступ программным путем с помощью класса PerformanceCounter в пространстве имен System.Diagnostics.

Доступные счетчики производительности

В настоящее время имеется 14 различных счетчиков производительности, доступных для Microsoft.Data.SqlClient, как показано в следующей таблице.

Счетчик производительности Description
HardConnectsPerSecond Количество соединений с сервером базы данных в секунду.
HardDisconnectsPerSecond Количество разрывов соединений с сервером базы данных в секунду.
NumberOfActiveConnectionPoolGroups Количество уникальных активных групп пулов соединений. Этот счетчик управляется числом уникальных строк соединения, найденных в домене приложения.
NumberOfActiveConnectionPools Общее число пулов соединений.
NumberOfActiveConnections Количество текущих активных соединений. Примечание. Этот счетчик производительности по умолчанию не включен. Инструкции о том, как его включить, см. в разделе Активация счетчиков, отключенных по умолчанию.
NumberOfFreeConnections Количество соединений, доступных в пулах соединений. Примечание. Этот счетчик производительности по умолчанию не включен. Инструкции о том, как его включить, см. в разделе Активация счетчиков, отключенных по умолчанию.
NumberOfInactiveConnectionPoolGroups Количество уникальных групп пулов соединений, отмеченных для усечения. Этот счетчик управляется числом уникальных строк соединения, найденных в домене приложения.
NumberOfInactiveConnectionPools Количество неактивных пулов соединений, не участвовавших в последних операциях и ожидающих удаления.
NumberOfNonPooledConnections Количество активных соединений, не помещенных в пулы.
NumberOfPooledConnections Количество активных соединений, которые управляются инфраструктурой пулов соединений.
NumberOfReclaimedConnections Количество соединений, затребованных сборкой мусора, в которой приложение не вызывает методы Close и Dispose. Примечание. Если подключения не закрывать и не удалять явно, производительность может снижаться.
NumberOfStasisConnections Количество соединений, ожидающих в настоящий момент завершения действия и поэтому доступных для приложения.
SoftConnectsPerSecond Количество активных соединений, извлекаемых из пула соединений. Примечание. Этот счетчик производительности по умолчанию не включен. Инструкции о том, как его включить, см. в разделе Активация счетчиков, отключенных по умолчанию.
SoftDisconnectsPerSecond Количество активных соединений, возвращаемых в пул соединений. Примечание. Этот счетчик производительности по умолчанию не включен. Инструкции о том, как его включить, см. в разделе Активация счетчиков, отключенных по умолчанию.

Активация счетчиков, отключенных по умолчанию

Счетчики производительности NumberOfFreeConnections, NumberOfActiveConnections, SoftDisconnectsPerSecond и SoftConnectsPerSecond отключены по умолчанию. Чтобы включить их, добавьте в файл конфигурации приложения следующие данные:

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

Получение значений счетчиков производительности

В следующем приложении командной строки показан способ получения значений счетчиков производительности. Чтобы возвратить данные для всех счетчиков производительности поставщика данных Microsoft SqlClient для SQL Server, подключения должны быть открыты и активны.

Примечание.

Здесь используется пример базы данных AdventureWorks. Строка подключения, представленная в примере кода, предполагает, что база данных установлена и доступна на локальном компьютере, и что созданы имена входа, соответствующие представленным в строках подключения. Имена входа SQL Server придется создать, если сервер использует параметры безопасности по умолчанию, разрешающие только проверку подлинности Windows. При необходимости измените строки соединения, чтобы они соответствовали среде.

Пример

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>;";
        }
    }
}

См. также