Compartir vía


Contadores de rendimiento en SqlClient

Se aplica a: .NET Framework

Descargar ADO.NET

Puede usar contadores de rendimiento de Microsoft.Data.SqlClient para supervisar el estado de la aplicación y los recursos de conexión que usa. Los contadores de rendimiento se pueden controlar con el Monitor de rendimiento de Windows pero también se puede tener acceso a ellos mediante programación usando la clase PerformanceCounter del espacio de nombres System.Diagnostics.

Importante

El PerformanceCounterenfoque basado en que se describe en este artículo requiere .NET Framework y solo se ejecuta en Windows. La System.Diagnostics.PerformanceCounter clase no está disponible en .NET Core, .NET 5 o plataformas que no son de Windows. Para la supervisión multiplataforma en aplicaciones modernas de .NET, use contadores de eventos en SqlClient en su lugar.

Contadores de rendimiento disponibles

Actualmente, hay 14 contadores de rendimiento distintos disponibles para Microsoft.Data.SqlClient, tal como se describe en la tabla siguiente.

Contador de rendimiento Descripción
HardConnectsPerSecond El número de conexiones por segundo que se establecen con un servidor de bases de datos.
HardDisconnectsPerSecond El número de desconexiones por segundo que se producen con un servidor de bases de datos.
NumberOfActiveConnectionPoolGroups El número de grupos únicos de pools de conexiones que están activos. Este contador depende del número de cadenas de conexión única que haya en el AppDomain.
NumberOfActiveConnectionPools El número total de grupos de conexiones.
NumberOfActiveConnections El número de conexiones activas que se están utilizando actualmente. Nota: Este contador de rendimiento no está habilitado de forma predeterminada. Para habilitar este contador de rendimiento, consulte Activación de contadores desactivados de manera predeterminada.
NumberOfFreeConnections El número de conexiones que se pueden utilizar en los grupos de conexiones. Nota: Este contador de rendimiento no está habilitado de forma predeterminada. Para habilitar este contador de rendimiento, consulte Activación de contadores desactivados de manera predeterminada.
NumberOfInactiveConnectionPoolGroups El número de conjuntos de grupos de conexiones únicas que están marcados para ser eliminados. Este contador depende del número de cadenas de conexión única que haya en el AppDomain.
NumberOfInactiveConnectionPools Número de grupos de conexiones inactivas que no han tenido ninguna actividad recientemente y que están a la espera de ser eliminadas.
NumberOfNonPooledConnections Número de conexiones activas que no están agrupadas.
NumberOfPooledConnections El número de conexiones activas que administra la infraestructura de agrupación de conexiones.
NumberOfReclaimedConnections Número de conexiones que se han recuperado mediante la recolección de basura cuando la aplicación no llamó a Close ni a Dispose. Nota: No cerrar o eliminar explícitamente las conexiones afecta el rendimiento.
NumberOfStasisConnections El número de conexiones que están actualmente en espera de que se finalice una acción y que por lo tanto no pueden ser utilizadas por la aplicación.
SoftConnectsPerSecond El número de conexiones activas que se extraen del grupo de conexiones. Nota: Este contador de rendimiento no está habilitado de forma predeterminada. Para habilitar este contador de rendimiento, consulte Activación de contadores desactivados de manera predeterminada.
SoftDisconnectsPerSecond El número de conexiones activas que están siendo devueltas al grupo de conexiones. Nota: Este contador de rendimiento no está habilitado de forma predeterminada. Para habilitar este contador de rendimiento, consulte Activación de contadores desactivados de manera predeterminada.

Activar contadores desactivados por defecto

Los contadores de rendimiento NumberOfFreeConnections, NumberOfActiveConnections, SoftDisconnectsPerSecond y SoftConnectsPerSecond están desactivados de forma predeterminada. Agregue la siguiente información al archivo de configuración de la aplicación para habilitarlos:

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

Recuperación de los valores de los contadores de rendimiento

La siguiente aplicación de consola muestra cómo recuperar valores de los contadores de rendimiento en su aplicación. Las conexiones deben estar abiertas y activas para que se devuelva la información de todos los contadores de rendimiento del proveedor de datos SqlClient de Microsoft para SQL Server.

Nota

En este ejemplo se usa la base de datos AdventureWorks de ejemplo. Las cadenas de conexión proporcionadas en el código de ejemplo suponen que la base de datos está instalada y disponible en el equipo local, y que ha creado inicios de sesión que coinciden con los proporcionados en las cadenas de conexión. Es posible que tenga que habilitar los inicios de sesión de SQL Server si el servidor está configurado mediante la configuración de seguridad predeterminada que solo permite la autenticación de Windows. Modifique las cadenas de conexión según sea necesario para su entorno.

Ejemplo

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

namespace SqlClient_PerformanceCounter
{
    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>;";
        }
    }
}