VENTAS: 1-800-867-1389

Consideraciones sobre el rendimiento con Base de datos SQL de Azure

Actualizado: enero de 2014

En este artículo se explican las prácticas recomendadas que mejoran el rendimiento de las aplicaciones que usan una base de datos que se ha migrado a Base de datos SQL de Microsoft Azure. Cuando un servidor de bases de datos comparte el mismo bastidor que el servidor de aplicaciones, puede que estas prácticas recomendadas no tengan un gran impacto. Sin embargo, cuando el servidor de bases de datos se mueve a un centro de datos remoto, estas mismas prácticas recomendadas son fundamentales para mantener un rendimiento óptimo. Además, Microsoft Azure es un entorno compartido en el que todos los recursos se comparten con otras aplicaciones, roles y bases de datos. Gracias al equilibrio de carga de red y los componentes de puerta de enlace, Azure mantiene la economía de escala, y proporciona recursos de proceso y de red de la manera más eficiente posible al entorno en conjunto. Tenga en cuenta estos factores al diseñar aplicaciones para Azure e implementar aplicaciones en esta plataforma.

En este artículo se explican las prácticas recomendadas de diseño e implementación para optimizar el rendimiento del entorno Base de datos SQL de Microsoft Azure. En concreto, se examinan las prácticas recomendadas para satisfacer dos áreas que pueden producir problemas en cuanto al rendimiento percibido cuando se migran bases de datos locales a Base de datos SQL de Microsoft Azure:

Hay otros artículos relacionados con el rendimiento de una base de datos de Azure como se describe a continuación:

Base de datos SQL de Azure ofrece la posibilidad de reservar recursos para la base de datos mediante la edición Premium que está disponible actualmente a través del programa de vista previa. El documento Guía de rendimiento de Base de datos SQL de Azure proporciona instrucciones que le ayudarán a determinar si la base de datos Premium que está disponible a través del programa de vista previa es adecuada para su aplicación y ofrece recomendaciones para optimizar la aplicación con el fin de sacar el máximo partido de esta característica.

En el artículo SQL Server y Base de datos SQL de Windows Azure: comparación y contraste del rendimiento y la escalabilidad se describen algunos patrones de rendimiento de Base de datos SQL y varias técnicas para evaluar correctamente el rendimiento, y se incluyen varios scripts SQL que pueden ayudarle a evaluar y solucionar los problemas de las instancias de Base de datos SQL.

  • Administración de las conexiones

  • Latencia de red entre la capa de aplicación y la capa de base de datos

Autores: Silvano Coriani y Steve Howard.
Revisores: Mark Simms, Valery Mizonov, Kun Cheng, Paolo Salvatori y Jaime Alva Bravo.

Las conexiones de base de datos se pueden interrumpir con más frecuencia cuando una base de datos se hospeda en Base de datos SQL de Microsoft Azure que en un entorno local. Los usuarios pueden percibir estas interrupciones como un problema de rendimiento si las aplicaciones no detectan rápidamente la pérdida de una conexión y vuelven a conectarse en caso de que se trate de un error temporal o transitorio. Como proveedor de servicios de base de datos a gran escala multiempresa en recursos compartidos, Base de datos SQL de Microsoft Azure agrupa cada base de datos en tres nodos y equilibra los recursos entre los nodos de clúster para proporcionar una buena experiencia a todos los inquilinos. Un ejemplo de error transitorio es cuando Base de datos SQL de Microsoft Azure detecta un uso intensivo de un servidor que hospeda varias bases de datos. En este caso, Base de datos SQL de Microsoft Azure puede conmutar por error una de las bases de datos a un nodo de clúster secundario que tenga una carga de procesamiento menor. La conmutación por error finaliza todas las conexiones abiertas a la base de datos y revierte las transacciones pendientes. Las aplicaciones deben detectar rápidamente el error, volver a conectarse a la base de datos e intentar de nuevo su última transacción.

En la lista siguiente se describen algunas de las razones por las que Base de datos SQL de Microsoft Azure puede finalizar conexiones:

  • La topología global de red de Base de datos SQL de Microsoft Azure incluye firewalls, equilibradores de carga y puertas de enlace de flujo TDS. Cada uno de estos componentes de la topología agrega un nivel entre el código de acceso a datos y el nodo de la base de datos. Los errores de estos niveles adicionales pueden finalizar conexiones.

  • Base de datos SQL de Microsoft Azure recopila y analiza continuamente estadísticas de uso de la base de datos. En función de esas estadísticas, Base de datos SQL de Microsoft Azure puede finalizar conexiones cuando sea necesario para mantener el servicio en buen estado.

  • Los ataques por denegación de servicio hacen que Base de datos SQL de Microsoft Azure impida las conexiones desde una dirección IP específica durante un período de tiempo determinado.

  • Algunos eventos de conmutación por error pueden hacer que Base de datos SQL de Microsoft Azure finalice precipitadamente una sesión. (Tenga en cuenta que cualquier conexión abierta en un nodo antes de un evento de conmutación por error no estará disponible en el nuevo nodo después de la conmutación por error).

La lista anterior muestra solo algunas de las razones por las que se finalizan las conexiones. Para obtener más información acerca de los errores de conexión y detalles sobre cómo administrar conexiones en Base de datos SQL de Microsoft Azure, vea los documentos siguientes:

Para ayudar a administrar los problemas de conexión de Base de datos SQL de Microsoft Azure, Microsoft proporciona la funcionalidad siguiente:

  • Un enfoque coherente sobre cómo especificar información básica, como nombres de servidor y credenciales de seguridad, o fidelidad total mediante herramientas como el programa de copia masiva (bpc.exe). Por ejemplo, a partir de SQL Server Native Client 11, la versión 4.0 de JDBC y el proveedor de datos de .NET Framework para SQL Server (System.Data.SqlClient) de .NET Framework 4.0, no es necesario especificar nombreDeUsuario@servidor para tener acceso a Base de datos SQL de Microsoft Azure.

  • Asegurarse de que todas las tecnologías de conexión pueden mantener una conexión, incluso durante los períodos de inactividad. Por ejemplo, a diferencia de Windows, la plataforma Java no administra de forma nativa los intervalos entre mensajes de mantenimiento de conexión para las conexiones de base de datos. Por tanto, los componentes de JDBC que se conectan a Base de datos SQL de Microsoft Azure requieren realizar algunos cambios en la configuración del Registro para asegurarse de que las conexiones inactivas no se quitan.
    Para obtener más información, vea el tema de MSDN Library Conectar con una base de datos en Base de datos SQL de Azure.

Además, Microsoft ha implementado continuamente diversas actualizaciones en la mayoría de las bibliotecas de acceso a datos y las versiones de servicio de Base de datos SQL de Microsoft Azure más comunes. Quizás la más importante de estas actualizaciones sea Bloqueo de aplicación para la administración de errores transitorios, una biblioteca de aplicaciones que proporciona lógica sólida para la administración de errores transitorios. (Los errores transitorios son los errores que se producen debido a una condición temporal como problemas de conectividad de red o la no disponibilidad del servicio). En la próxima sección se ofrece una visión general de cómo aplicar el Bloqueo de aplicación para la administración de errores transitorios a una aplicación.

El Bloqueo de aplicación para la administración de errores transitorios encapsula información sobre los errores transitorios que pueden producirse cuando se usan los siguientes servicios de Azure en su aplicación:

  • Base de datos SQL de Microsoft Azure

  • Service Bus de Azure

  • Almacenamiento de Azure

  • Servicio Caching de Azure

Cada uno de estos servicios puede tener errores transitorios diferentes. Así, el Bloqueo de aplicación para la administración de errores transitorios usa directivas de detección de errores específicas para cada servicio. Del mismo modo, las distintas aplicaciones requieren estrategias de administración de errores diferentes. Para dar cabida a estas diferencias, el Bloqueo de aplicación para la administración de errores transitorios proporciona distintos enfoques de lógica de reintento dirigidos a los diversos escenarios de errores transitorios. Estas directivas listas para usar se pueden mejorar creando clases personalizadas que expongan interfaces bien definidas.

El uso del Bloqueo de aplicación para la administración de errores transitorios dentro de aplicaciones existentes tiene muy poco impacto. Según su diseño, el Bloqueo de aplicación para la administración de errores transitorios ofrece varias clases y métodos de extensión que imitan el comportamiento de un nivel típico de acceso a datos de ADO.NET.

Para mostrar la facilidad de uso de esta biblioteca de aplicaciones, en los párrafos siguientes se muestra cómo aplicar el Bloqueo de aplicación para la administración de errores transitorios a código existente. En el ejemplo siguiente se muestra un método simple que consulta una base de datos y consume el conjunto de resultados:

        public static void ReadFromDB()
        {

            using (SqlConnection conn = new SqlConnection(connString))
            {
                try
                {
                    conn.Open();

                    SqlCommand selectCommand = 
new SqlCommand(@"SELECT SOH.SalesOrderID
                         FROM SalesLT.SalesOrderHeader SOH 
                         JOIN SalesLT.SalesOrderDetail SOD ON SOH.SalesOrderID = SOD.SalesOrderID
                         JOIN SalesLT.Product P ON SOD.ProductID = P.ProductID
                         JOIN SalesLT.Customer C ON SOH.CustomerID = C.CustomerID
                         JOIN SalesLT.CustomerAddress CA on C.CustomerID = CA.CustomerID
                         JOIN SalesLT.Address A on CA.AddressID = A.AddressID
                         WHERE A.City=@City", conn);

                    selectCommand.Parameters.Add(new SqlParameter("@City", SqlDbType.VarChar, 20, ParameterDirection.Input, false, 0, 0, "", DataRowVersion.Current, "London"));
                    selectCommand.CommandType = CommandType.Text;

                    IDataReader dataReader = selectCommand.ExecuteReader();

                    while (dataReader.Read())
                    {
                        Console.WriteLine("OrderID: {0}", dataReader["SalesOrderID"]);
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine("Exception: {0}",e.Message);
                }
            }

Para que este código sea más sólido, defina primero una estrategia adecuada de reintentos. Es mejor usar una estrategia incremental de reintentos. Para implementar esta estrategia, use primero la clase Microsoft.Practices.EnterpriseLibrary.WindowsAzure.TransientFaultHandling.SqlAzure.SqlAzureTransientErrorDetectionStrategy. Esta clase intercepta los códigos de error relacionados con las condiciones de error transitorias. A continuación, sustituya la clase System.Data.SqlClient SqlConnection con la clase Microsoft.Practices.EnterpriseLibrary.WindowsAzure.TransientFaultHandling.SqlAzure.ReliableSqlConnection, como se muestra en el ejemplo de código siguiente:

        public static void ReadFromDBWithReliableConnection()
        {

            // Define retry Strategy and Policy
            var retryStrategy = new Incremental(5, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2));
            var retryPolicy = new RetryPolicy<SqlAzureTransientErrorDetectionStrategy>(retryStrategy);

            // Receive notifications about retries.
            retryPolicy.Retrying += new EventHandler<RetryingEventArgs>(retryPolicy_Retrying);

            using (ReliableSqlConnection conn = new ReliableSqlConnection(connString,retryPolicy))
            {
                try
                {
                    conn.Open();

                    SqlCommand selectCommand = new SqlCommand(@"SELECT SOH.SalesOrderID
                                        FROM SalesLT.SalesOrderHeader SOH 
                                        JOIN SalesLT.SalesOrderDetail SOD ON SOH.SalesOrderID = SOD.SalesOrderID
                                        JOIN SalesLT.Product P ON SOD.ProductID = P.ProductID
                                        JOIN SalesLT.Customer C ON SOH.CustomerID = C.CustomerID
                                        JOIN SalesLT.CustomerAddress CA on C.CustomerID = CA.CustomerID
                                        JOIN SalesLT.Address A on CA.AddressID = A.AddressID
                                        WHERE A.City=@City");

                    selectCommand.Parameters.Add(new SqlParameter("@City", SqlDbType.VarChar, 20, ParameterDirection.Input, false, 0, 0, "", DataRowVersion.Current, "London"));
                    selectCommand.CommandType = CommandType.Text;

                    IDataReader dataReader = conn.ExecuteCommand<IDataReader>(selectCommand);

                    while (dataReader.Read())
                    {
                        Console.WriteLine("OrderID: {0}", dataReader["SalesOrderID"]);
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine("Exception: {0}", e.Message);
                }
            }
        
        }

El ejemplo de código anterior, mientras agregaba la lógica adecuada de reintentos, también reemplazaba el código existente SQLConnection con el código ReliableSQLConnection. Para minimizar la cantidad de código que hay que volver a escribir, existe un método alternativo que consiste en usar los métodos de extensión proporcionados con el Bloqueo de aplicación para la administración de errores transitorios. Este método no solo reduce al mínimo la cantidad de reescritura necesaria, sino que también ofrece una manera genérica de agregar capacidades de reintento a una aplicación de ADO.NET. Para usar los métodos de extensión, reemplace el método Open() y varios métodos Execute (como ExecuteScalar(), ExecuteReader() o ExecuteNonQuery()) con sus equivalentes con capacidad de reintento, como OpenWithRetry() o ExecuteScalarWithRetry(). Esto se muestra en el ejemplo de código siguiente:

        public static void ReadFromDBWithExecute()
        {

            // Define retry Strategy and Policy
            var retryStrategy = new Incremental(5, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2));
            var retryPolicy = new RetryPolicy<SqlAzureTransientErrorDetectionStrategy>(retryStrategy);

            // Receive notifications about retries.
            retryPolicy.Retrying += new EventHandler<RetryingEventArgs>(retryPolicy_Retrying);

            try
            {
                retryPolicy.ExecuteAction(
                  () =>
                  {
                      using (SqlConnection conn = new SqlConnection(connString))
                      {
                          conn.OpenWithRetry();

                          SqlCommand selectCommand = new SqlCommand(@"SELECT SOH.SalesOrderID
                                                FROM SalesLT.SalesOrderHeader SOH 
                                                JOIN SalesLT.SalesOrderDetail SOD ON SOH.SalesOrderID = SOD.SalesOrderID
                                                JOIN SalesLT.Product P ON SOD.ProductID = P.ProductID
                                                JOIN SalesLT.Customer C ON SOH.CustomerID = C.CustomerID
                                                JOIN SalesLT.CustomerAddress CA on C.CustomerID = CA.CustomerID
                                                JOIN SalesLT.Address A on CA.AddressID = A.AddressID
                                                WHERE A.City=@City",conn);

                          selectCommand.Parameters.Add(new SqlParameter("@City", SqlDbType.VarChar, 20, ParameterDirection.Input, false, 0, 0, "", DataRowVersion.Current, "London"));
                          selectCommand.CommandType = CommandType.Text;

                          // Execute the above query using a retry-aware ExecuteCommand method which will
                          // automatically retry if the query has failed (or connection was dropped)
                          IDataReader dataReader = selectCommand.ExecuteReaderWithRetry(retryPolicy);
                          
                            while (dataReader.Read())
                            {
                                Console.WriteLine("OrderID: {0}", dataReader["SalesOrderID"]);
                            }                          
                      }
                  });
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception: {0}", e.Message );
            }

        }

El Bloqueo de aplicación para la administración de errores transitorios admite la declaración de directivas configurables de reintentos. Para obtener más información acerca de cómo declarar directivas de reintentos, vea Especificar estrategias de reintento en la configuración

Los ejemplos de código mostrados aquí proporcionan una vista rápida de cómo usar el Bloqueo de aplicación para la administración de errores transitorios. Hay información más detallada sobre cómo usar esta biblioteca de aplicaciones en un tutorial del wiki de TechNet: Lógica de reintento para errores transitorios en Base de datos SQL de Azure

Además de los errores de conexión, la latencia de red es el otro problema de rendimiento más frecuente que perciben los usuarios actuales de Base de datos SQL de Microsoft Azure.

Si bien el impacto de la latencia de Internet es muy conocido, los usuarios tienden a subestimar el impacto de la latencia entre la aplicación y Base de datos SQL de Microsoft Azure. Incluso aunque el mismo centro de datos hospede la aplicación y las bases de datos, la latencia suele ser mayor que la de un entorno local tradicional. Esta latencia mayor proviene de la naturaleza multiempresa de Azure. Además, esta latencia mayor amplifica el efecto de los comportamientos de las aplicaciones “locuaces”, ya que cada llamada a la base de datos experimentará la latencia adicional que podría acumularse hasta llegar a una degradación del rendimiento global. Por tanto, las aplicaciones “locuaces” tardan mucho más tiempo en obtener acceso a una base de datos hospedada en Base de datos SQL de Microsoft Azure que una base de datos de SQL Server hospedada de forma local.

Además de la latencia entre la aplicación y Base de datos SQL de Microsoft Azure, hay una latencia mayor en las comunicaciones entre los diferentes componentes distribuidos de la solución. Este tipo de latencia es quizás una de las mayores diferencias entre las aplicaciones locales y de la nube. Este tipo de latencia se produce para las comunicaciones entre el usuario y la aplicación, y entre la aplicación y Base de datos SQL de Microsoft Azure.

Desde la perspectiva del usuario final, todas estas causas de la latencia de red corresponden al siguiente tiempo de respuesta percibido para un usuario:

Tiempo de respuesta = 2 x (Latencia_1 + Latencia_2) + Tiempo_de_procesamiento_de_aplicación + Tiempo_de_ejecución_de_consulta

Donde

  • Latencia_1 es la latencia entre el usuario final y el centro de datos que hospeda la aplicación. (Este tipo de latencia también se puede encontrar en entornos locales).

  • Latencia_2 es la latencia entre la aplicación y las bases de datos en Base de datos SQL de Microsoft Azure.

Para garantizar la optimización del rendimiento, se recomienda realizar primero las acciones básicas siguientes:

  • Minimizar Latencia_1 seleccionando un centro de datos más cercano a la mayoría de los usuarios.

  • Minimizar Latencia_2 colocando los datos con la aplicación de Azure para minimizar las operaciones de ida y vuelta en la red.

  • Minimizar Tiempo_de_procesamiento_de_aplicación y Tiempo_de_ejecución_de_consulta siguiendo las prácticas recomendadas generales que usaría para las bases de datos locales al tener acceso al nivel de datos, controlar el rendimiento y codificar pensando en la optimización.

Es importante mantener las bases de datos hospedadas lo más cerca posible del lugar donde se ejecuta la aplicación. Si la aplicación se ejecuta en el centro de datos de EE. UU. Central Norte, si hospeda la base de datos en el centro de datos de EE. UU. Central Norte obtendrá la acción de ida y vuelta más corta y, por tanto, la menor latencia en relación con la distancia.

Si bien es posible obtener acceso a una base de datos hospedada en Azure desde una aplicación local, tenga en cuenta que esto dará como resultado una latencia mayor para el acceso a datos y también producirá gastos por salida de datos del centro de datos.

En aquellos caso en los que sea necesario tener acceso a datos en varias configuraciones regionales geográficas, use Red de entrega de contenido para distribuir datos estáticos entre varios sitios. O bien, cree varias copias de una base de datos en diferentes centros de datos y use SQL Data Sync (Vista previa) para sincronizar los datos entre ellas. Estos enfoques son útiles para las aplicaciones que se ejecutan en varios sitios geográficos al colocar los datos más cerca de las distintas instancias de la aplicación y reducir la latencia total.

noteNota
SQL Data Sync (Vista previa) solo está disponible actualmente como versión preliminar y su fin es solo servir como origen de comentarios sobre el producto para las versiones futuras; no debe usarse en entornos de producción.

Minimizar los ciclos de ida y vuelta de red, si bien es importante para una aplicación local, es especialmente importante con Azure. Las consultas procesadas por Base de datos SQL de Microsoft Azure deben pasar por los niveles de equilibrio de carga de red, así como por la puerta de enlace del protocolo TDS antes de que Base de datos SQL de Microsoft Azure las reciba. Aunque esta abstracción permite a Base de datos SQL de Microsoft Azure proporcionar escalado y disponibilidad al usuario final, también requiere un cierta cantidad de procesamiento que da como resultado una pequeña cantidad de latencia en cada acción de ida y vuelta. Las aplicaciones que envían datos a Base de datos SQL de Microsoft Azure en muchas acciones de ida y vueltas secuenciales pueden experimentar una disminución significativa del rendimiento.

Para minimizar los efectos de las acciones de ida y vueltas, siga las mismas prácticas recomendadas que en el caso de las aplicaciones locales:

  • Use procedimientos almacenados, especialmente para encapsular lógica compleja de acceso de datos y comportamientos transaccionales: cuando se realizan llamadas secuenciales en las que la segunda llamada depende de los datos devueltos por la primera, el uso de un procedimiento almacenado para realizar la lógica para la segunda llamada elimina una o varias acciones de ida y vuelta y acelera el rendimiento. Este enfoque reducirá las acciones de ida y vuelta, y el bloqueo y el uso de recursos en el lado servidor.

  • Minimice el uso de cursores o el acceso fila a fila: use operaciones basadas en conjuntos siempre que sea posible. Si se deben usar cursores, emplee un cursor del lado cliente.

  • Use parámetros con valores de tabla para enviar varias filas a Base de datos SQL de Microsoft Azure en cada acción de ida y vuelta:Base de datos SQL de Microsoft Azure usa parámetros con valores de tabla como ocurre en las versiones locales del Motor de base de datos de SQL Server. Los parámetros con valores de tabla ayudan a reducir varias llamadas al mismo procedimiento almacenado para procesar un conjunto de registros o de valores. También puede pasar parámetros tabulares a una sola consulta con parámetros, como un comando SELECT, INSERT, UPDATE o DELETE.
    Para obtener más información, vea el tema siguiente de los Libros en pantalla: Usar parámetros con valores de tabla.

  • Use el almacenamiento en caché local siempre que sea posible: el almacenamiento en caché local puede permitirle reutilizar los mismos resultados sin varias acciones de ida y vuelta a Base de datos SQL de Microsoft Azure. Tenga en cuenta también que puede almacenar en caché llamadas a procedimientos almacenados que devuelven el mismo valor si se les proporciona el mismo.

  • Use Caching de Azure siempre que sea posible: use Caching de Azure para los datos de búsqueda de solo lectura con el fin de minimizar el tráfico de red a Base de datos SQL de Microsoft Azure. Para obtener más información, vea Reducir los ciclos de ida y vuelta de red mediante Caching de Azure.

  • Almacene en caché los metadatos y los datos siempre que sea posible.

  • Evite la recuperación de metadatos en tiempo de ejecución siempre que sea posible.

  • Evite clases como SqlCommandBuilder: estas clases consultan metadatos en tiempo de ejecución, lo que da como resultado ciclos de ida y vuelta adicionales.

  • Instrucciones SQL por lotes juntas siempre que sea posible: puede concatenar varias instrucciones Transact-SQL en un único comando por lotes para recuperar varios conjuntos de resultados o ejecutar varias operaciones DML en una única acción de ida y vuelta de red. Este enfoque es especialmente válido cuando se trata con grandes cantidades de operaciones INSERT consecutivas.

  • Evite la administración de transacciones basadas en aplicaciones: encapsular las operaciones de administración de transacciones (BEGIN TRAN, COMMIT/ROLLBACK) en procedimientos almacenados puede reducir los ciclos de ida y vuelta y los bloqueos de red.

Una vez minimizada la distancia entre los datos y los usuarios, y las acciones de ida y vuelta de red, el paso siguiente consiste en asegurarse de que la aplicación sigue las prácticas recomendadas generales para las bases de datos locales. Al aplicar las prácticas recomendadas y recomendaciones conocidas al nivel de acceso a datos de la aplicación, junto con las prácticas recomendadas de rendimiento y optimización, debe observar un efecto beneficioso “multiplicado” en un entorno de latencia elevada como es la nube.

Entre las prácticas recomendadas generales para la interacción de la base de datos con bases de datos locales se incluyen las siguientes:

  • Abra una conexión tarde y ciérrela lo antes posible: para minimizar el uso de recursos y la posibilidad de limitación, abra una conexión en la aplicación únicamente en el punto en el que el código necesite esa conexión. Además, devuelva la conexión al grupo inmediatamente después de que el código termine con la conexión desechando el objeto de conexión. (Una excepción a esta directiva de devolución es cuando hay más trabajo inmediato que completar. En este caso, devuelva la conexión solo cuando se haya completado todo el trabajo más inmediato).

  • Aproveche la agrupación de conexiones: en el nivel de proceso, los grupos de conexiones contendrán conexiones dirigidas a la misma base de datos y que usan el mismo contexto de seguridad. Siempre que sea posible, use la misma cadena de conexión para todas las conexiones que tengan las mismas características.

  • Recupere solo los datos que necesite: defina cuidadosamente la lista de selección y la cláusula WHERE. Este enfoque permite minimizar el uso de ancho de banda de red y también permite indizar eficazmente la base de datos pensando en el rendimiento.

  • Haga que las transacciones sean lo más cortas posible y evite implicar a recursos innecesarios: el diseño poco óptimo del modelo de datos y el número excesivo de ciclos de ida y vuelta entre el código de la aplicación y las bases de datos son problemas frecuentes, pero no son críticos en las implementaciones locales porque se trata de un entorno de conectividad de baja latencia. Estas aplicaciones también pueden ser difíciles de modificar debido a las razones siguientes:

    • Restricciones arquitectónicas existentes.

    • Diseño monolítico donde el acceso a datos y la lógica de negocios están conectados estrechamente y son interdependientes.

    • Algunos aspectos, como el procesamiento de datos fila a fila, que la propia lógica de aplicación necesita y son difíciles de modificar sin una reescritura masiva.

Además de estas prácticas recomendadas generales, existen otras adicionales relacionadas con las tecnologías que se usan en la aplicación. Por ejemplo, las aplicaciones que usan .NET Framework pueden emplear tecnologías como ADO.NET, Entity Framework y WCF Data Services. Estas tecnologías ofrecen menores tiempos de desarrollo y proporcionan mayor flexibilidad a la hora de implementar el nivel de acceso a datos para cualquier estilo de aplicación. Estas tecnologías también encajan bien con una orientación a servicios al desacoplar niveles, ofrecer flexibilidad del esquema, usar arquitecturas abiertas de datos (por ejemplo, OData) y ofrecer un diseño “desconectado” por naturaleza. A pesar de sus beneficios, estas tecnologías pueden generar la misma clase de problemas que se han descrito para las aplicaciones heredadas, como locuacidad, si no tiene en cuenta una optimización adecuada del diseño y la operación de datos (esto incluye representación de datos óptima, uso de memoria caché y operaciones por lotes relacionadas con datos para reducir los ciclos de ida y vuelta innecesarios).

En las próximas secciones se describen algunas de las prácticas recomendadas para estas tecnologías, así como el empleo de programación asincrónica en las aplicaciones Azure.

Para las bibliotecas de acceso a datos, como ODBC y JDBC, donde la compatibilidad del cliente con operaciones inteligentes (como ordenación, filtrado, etc.) es limitada, todavía puede aplicar técnicas de optimización existentes como reducir las operaciones basadas en cursor y el procesamiento fila a fila. Cuando sea necesario usar cursores, use cursores de solo lectura y de solo avance para recuperar valores, y emplee comandos SQL para realizar modificaciones en los datos en lugar de usar actualizaciones posicionadas en cursores.

Con ADO.NET, existen diversas optimizaciones que se pueden aplicar para maximizar la eficacia del código de acceso a datos:

  • Elija el modo de ejecución adecuado con SqlCommand: por ejemplo, si solo necesita recuperar un valor escalar, use el método ExecuteScalar(), o ExecuteNonQuery() si no necesita recuperar un conjunto de resultados

  • Use la propiedad UpdateBatchSize cuando emplee la clase SqlDataAdapter para ejecutar varias operaciones: agrupa por lotes varios comandos a medida que se transmiten a través de la red, lo que minimiza los ciclos de ida y vuelta de red.

  • Use SqlDataAdapter para implementar interacciones directas con la base de datos mediante el uso de procedimientos almacenados para operaciones SELECT, INSERT, UPDATE y DELETE.

  • Establezca la propiedad SerializationFormat en Binary cuando use conjuntos de datos como la caché del lado cliente: esto reduce la cantidad de datos transmitidos a través del cable.

En lo que respecta al desarrollo de acceso a datos, hay mucho interés en Entity Framework por las razones siguientes:

  • Proporciona un entorno completo de asignación de objeto a relacional que puede reducir drásticamente el tiempo de desarrollo.

  • Presenta más flexibilidad al desacoplar la definición física del esquema de la base de datos de la representación conceptual de los datos de la aplicación.

  • Proporciona un conjunto completo de servicios para abordar la persistencia.

  • Reduce los ciclos de ida y vuelta de red, ya que es capaz de cargar conjuntos de resultados de Base de datos SQL de Microsoft Azure en conjuntos de objetos en la memoria de la aplicación y reutilizarlos en un modo sin conexión sin necesidad de interactuar con el back-end para cada operación.

Sin embargo, como ocurre con cualquier otra herramienta de programación, Entity Framework puede producir algunos problemas de rendimiento si no presta una atención específica al tratar con interacciones de base de datos. Además, el entorno Azure amplifica estos aspectos de rendimiento.

Para optimizar el uso de Entity Framework con Base de datos SQL de Microsoft Azure, siga estas instrucciones:

  • Deshabilite explícitamente el seguimiento del estado de los objetos en el nivel de ObjectStateManager para las entidades y las relaciones: aplique esta instrucción si la aplicación no necesita hacer un seguimiento del estado de los objetos porque se trata de un uso típico de solo lectura.

  • Deshabilite la carga diferida para controlar mejor la interacción entre el código y la base de datos: para reducir los ciclos de ida y vuelta, cargaría previamente todo lo que necesita en una sola interacción. Puede procesar por lotes varios comandos tanto al cargar como al conservar datos en el almacén de datos extendiendo el contexto del objeto con métodos específicos.

  • Use procedimientos almacenados para las interacciones con el almacén de datos siempre que sea posible: cuando no se puedan usar procedimientos almacenados, use consultas con parámetros y vistas indizadas para mejorar el rendimiento.

  • Ejecute varias operaciones de base de datos en un único ciclo de ida y vuelta integrando parámetros con valores de tabla y asignando conjuntos de objetos a parámetros tabulares de procedimientos almacenados: puede usar este enfoque aunque no lo admitan directamente las herramientas de diseño.

  • Asigne varios conjuntos de resultados a objetos en una sola operación siempre que sea posible.

  • Asigne conjuntos de objetos al método System.Data.SqlClient.SqlBulkCopy.WriteToServer() para las actividades masivas de inserción de datos: el método SQLBulkCopy permite al motor de base de datos de SQL Server y a Base de datos SQL de Microsoft Azure usar optimizaciones de registro de operaciones masivas, de forma que las inserciones grandes se realizan más rápidamente en muchos casos.

Para obtener más información, vea El uso de Entity Framework para reducir la latencia de red con Base de datos SQL de Azure.

Algunas operaciones de base de datos, como las ejecuciones de comandos, pueden tardar mucho tiempo en completarse. En estos casos, las aplicaciones con un único subproceso deben bloquear otras operaciones y esperar hasta que el comando finaliza antes de continuar con otras operaciones. En cambio, la asignación de la operación de ejecución prolongada a un subproceso en segundo plano permite que el subproceso en primer plano permanezca activo durante toda la operación.

ADO.NET admite estos mismos patrones de diseño en su clase SqlCommand. Concretamente, al emparejar los métodos BeginExecuteNonQuery(), BeginExecuteReader() y BeginExecuteXmlReader() con los métodos EndExecuteNonQuery(), EndExecuteReader() y EndExecuteXmlReader(), respectivamente, ofrece compatibilidad asincrónica.

Estos métodos asincrónicos no le evitarán aplicar todas las optimizaciones y las prácticas recomendadas mencionadas en las secciones anteriores. Sin embargo, al permitir la ejecución de otras operaciones en paralelo con la consulta en Base de datos SQL de Microsoft Azure, estos métodos asincrónicos ayudan a reducir el efecto de las operaciones de base de datos de ejecución prolongada en el nivel de acceso a datos.

¿Te ha resultado útil?
(Caracteres restantes: 1500)
Gracias por sus comentarios
Mostrar:
© 2014 Microsoft