VENTAS: 1-800-867-1389

SQL Server y Base de datos SQL de Windows Azure: comparación y contraste del rendimiento y la escalabilidad

Actualizado: enero de 2014

Autores: Conor Cunningham, Tobias Ternström, Silvano Coriani, Ewan Fairweather

Autores colaboradores: Ralph Squillace, Karthika Raman

Aunque SQL Server y las Bases de datos SQL de Windows Azure (Base de datos SQL para abreviar, antes SQL Azure) tienen grandes e importantes similitudes, no son idénticos y, aunque las diferencias son relativamente pequeñas, afectan al modo en que las aplicaciones se ejecutan en la Base de datos SQL en comparación con SQL Server. Como resultado, la arquitectura de la aplicación y las técnicas de evaluación del rendimiento de cada plataforma también difieren.

Este documento explica estas diferencias en el rendimiento y sus causas e incluye lo que los clientes reales han aprendido a partir de la experiencia que les ha aportado solucionar los problemas del rendimiento en las Bases de datos SQL de los clientes en producción. Este documento también examina las técnicas habituales de evaluación del rendimiento de SQL Server que no funcionan en la Base de datos SQL. Para obtener una explicación más amplia del diseño de las aplicaciones de alto rendimiento y de gran escala de Windows Azure, vea Prácticas recomendadas para el diseño de servicios a gran escala en los Servicios en la nube de Windows Azure.

Es importante destacar que SQL Server, además de ejecutarse de forma local, también se puede ejecutar en una máquina virtual de Windows Azure. Las comparaciones y el método que se explican en este documento son aplicables a SQL Server independientemente de si este se ejecuta en un entorno local o en una máquina virtual de Windows Azure. Sin embargo, cuando SQL Server se ejecuta en una máquina virtual de Windows Azure, hay que tener en cuenta ciertas consideraciones de rendimiento adicionales. Esto se explica en detalle en el artículo Guía de rendimiento para SQL Server en Máquinas virtuales de Windows Azure.

Base de datos SQL de Windows Azure ofrece la posibilidad de reservar recursos para la base de datos mediante la edición Premium. Para obtener más información, vea Instrucciones para la edición Premium para Base de datos SQL de Windows Azure.

La estructura de este artículo es la siguiente.

Primero, se describen varios escenarios de aplicación estándar y los métodos y los patrones de aplicación que utilizan normalmente.

En segundo lugar, se describen varias expectativas comunes que los clientes tienen para la Base de datos SQL y las maneras en las que dichas expectativas pueden conducir a soluciones menos efectivas.

En tercer lugar, el tema se centra primero en los patrones clásicos que buscan un buen rendimiento en entornos compartidos para zambullirse a continuación con un poco más de profundidad en algunos modelos de rendimiento para la Base de datos SQL en particular.

En cuarto lugar, en el tema se describen varias técnicas generales de evaluación del rendimiento para las bases de datos relacionales.

En quinto lugar, el tema explica varias técnicas para evaluar correctamente el rendimiento de las instancias de la Base de datos SQL, dado que las características disponibles son diferentes de las de SQL Server.

En sexto lugar, el apéndice proporciona varios scripts SQL que pueden ayudarle a evaluar y solucionar los problemas de las instancias de la Base de datos SQL.

Al hacer frente a la optimización y el análisis del rendimiento, los diversos patrones de aplicación requieren métodos diferentes debido a las distintas arquitecturas y requisitos técnicos. Estas diferencias pueden ocasionar dificultades a la hora de definir un conjunto común de prácticas recomendadas y técnicas para medir y entender las características de rendimiento. Sin embargo, hay modelos comunes que se pueden utilizar para clasificar las aplicaciones y generalizar la forma de proceder. En esta sección se describen algunos modelos comunes que la Base de datos SQL de Windows Azure ha usado en las aplicaciones hasta la fecha.

Este grupo contiene las aplicaciones empresariales tradicionales (contabilidad, CRM, ERP, etc.) que adoptan el modelo de entrega de software como servicio (o SaaS) y que con frecuencia se relacionan con la implementación de un nuevo modelo empresarial o se destinan a nuevos segmentos de clientes. Los mayores desafíos que una empresa tradicional de desarrollo de software afronta al pasar a un nuevo modelo de entrega de software son los problemas relacionados con la base de código existente y con los métodos y conocimientos de sus empleados. El paso a un modelo SaaS implica intrínsecamente la adopción de un modelo de varios inquilinos como medio de hospedar varios clientes en el mismo conjunto de recursos físicos. Esto maximiza las inversiones de hardware y reduce los costos de administración, pero suele requerir rediseñar la aplicación centrándola especialmente en el nivel de la capa de datos para expandir los datos en varias bases de datos al tiempo que se mantiene su coherencia. Una expectativa común es que la plataforma se comportará “como el equivalente local”, aunque el entorno esté hospedado y los recursos de hardware se suelan compartir con otras aplicaciones.

Este escenario suele implicar la migración de las aplicaciones existentes de procesamiento por lotes de un entorno caro para conseguir ahorrar costos tanto en las licencias como en el mantenimiento. Para las aplicaciones de gran sistema, una gran parte de la lógica de negocios existente (normalmente COBOL) tendrá que conservarse tal cual debido a la complejidad o a las dificultades que supone conservar el conocimiento interno necesario para reescribir el código, especialmente si se ha escrito hace mucho tiempo. Estos entornos tienen que evaluarse cuidadosamente para saber qué grado de optimización y ajuste debe realizarse para que se ejecuten correctamente en Windows Azure. Aunque eso puede resultar tedioso, la experiencia demuestra que, con frecuencia, estos tipos de aplicaciones no suelen tener requisitos de latencia estrictos y en cambio requieren un rendimiento suficiente para completar grandes trabajos por lotes en el período de tiempo requerido.

Las plataformas en la nube como Windows Azure suelen ser el entorno ideal para proyectos de aplicaciones personalizadas. Estas aplicaciones se suelen desarrollar proyecto por proyecto, implementando nuevos procesos empresariales en función de los marcos de trabajo que se desarrollan, se mejoran y se reutilizan en varios proyectos. Un requisito común de este tipo de trabajo de desarrollo de software es la posibilidad de que la plataforma en la nube admita funciones de conectividad e híbridas como la replicación y sincronización de datos, la orquestación de procesos, la integración, etcétera. El tiempo de comercialización y la implementación y el desarrollo rápido de soluciones son fundamentales para estos tipos de proyectos. Esto también requiere una forma inmediata de detectar, analizar y solucionar los cuellos de botella de rendimiento y los problemas de escalabilidad.

Este modelo representa los nuevos proyectos de desarrollo de software importantes creados directamente en un entorno en la nube que implica cierto grado de riesgo empresarial. Estos tipos de aplicaciones se desarrollan, se prueban y se pasan a producción en la nube, y nunca estarán en ningún otro lugar. Debido a la complejidad inherente de la ejecución de la aplicación y los servicios a escala, es muy importante entender el comportamiento y el rendimiento de la aplicación y de la plataforma en la nube que la hospeda para conocer lo más completamente posible cómo encaja con los requisitos empresariales, el modelo de costos y las expectativas de rendimiento y de escala. Ejecutar este tipo de aplicaciones suele requerir cierto equilibrio entre el costo del desarrollo y los riesgos de la inversión.

Este tipo de aplicación suele ser una posibilidad novedosa: probablemente nunca habría existido sin el entorno masivamente escalable y elástico que las plataformas en la nube proporcionan. Los proveedores de aplicación a menudo han intentado antes implementar la aplicación con una arquitectura tradicional en un centro de datos tradicional, pero no tuvieron éxito debido a la carga de trabajo imprevisible generada por la base de usuarios y a las dificultades y los costos que supone diseñar una infraestructura tradicional para la carga máxima, por no hablar de su administración una vez diseñada y creada. Los, con frecuencia, elevados requisitos de visibilidad esenciales para la empresa requieren un método completamente nuevo para diseñar e implementar una solución con particiones completamente escalable tanto en la capa de aplicación como en la capa de datos. Con un mayor grado de complejidad, la capacidad de analizar y solucionar rápidamente los problemas relacionados con el rendimiento de la aplicación de extremo a extremo es un requisito desde las primeras etapas de la implementación.

Una creencia común de los nuevos usuarios de la Base de datos SQL es:

La Base de datos SQL es una versión inferior de SQL Server de bajo costo, elástica, altamente disponible y con poca sobrecarga de administración que se proporciona como servicio.

Esto es básicamente cierto. La Base de datos SQL es muy similar a SQL Server:

  • Admite un subconjunto grande del área expuesta de programación de SQL Server (que incluye tanto TDS como T-SQL, tiene una base de datos maestra, usa la autenticación de SQL, etc.).

  • Reutiliza una versión del motor de SQL Server para su funcionalidad básica de RDBMS.

  • El aprendizaje que requieren los clientes para comenzar a trabajar en la nueva plataforma es mínimo.

Sin embargo, las aplicaciones de producción no se crean en este nivel de abstracción. Como resultado, al diseñar las aplicaciones es esencial ir más allá de este nivel de conocimiento y conocer específicamente las diferencias principales entre SQL Server y la Base de datos SQL, por qué existen estas diferencias y qué se hace de distinta forma en la Base de datos SQL para asegurarse de que la aplicación se ejecuta de un modo eficaz y correcto.

A continuación se proporcionan tres ejemplos importantes en los que la experiencia aportada por SQL Server difiere de la de la Base de datos SQL. Las tres áreas siguientes son las tres áreas más importantes que hay que dominar para diseñar una aplicación de modo que se ejecute en la escala y el rendimiento apropiados, y se obtengan los mejores costos ahora y en el futuro.

  • Latencia

  • Hardware

  • Capacidad de recursos

A continuación se ofrecen más detalles sobre cada una de ellas:

 

Concepto SQL Server Base de datos SQL

Latencia

Se puede controlar con precisión cómo se colocan los servidores y cómo se conectan. La latencia típica entre un servidor de aplicaciones y SQL Server es inferior a los milisegundos. En la mayoría de los casos, una aplicación que realiza un gran número de llamadas de base de datos para completar una única operación está comportándose de forma aceptable.

En la Base de datos SQL, la comunicación habitual entre un servicio Windows Azure y una Base de datos SQL se produce en el orden de pocos milisegundos, que a menudo es un orden de una magnitud mayor que en local.

Hardware

Las empresas adquieren hardware de grado empresarial y hay personal de TI en plantilla que garantiza que se disponga de un equipo apropiado para el trabajo. Los errores de los equipos son muy raros y hay pocas razones para emplear tiempo en aportar flexibilidad en las conexiones o los comandos a través, por ejemplo, de reintentos automáticos de las operaciones con errores en la aplicación. Las actualizaciones y el servicio se realizan según una programación publicada con tiempo de inactividad planeado.

Windows Azure se creó en aras de la economía de la nube y utiliza hardware de servicio y equipos similares en todo el servicio. Estos equipos son menos eficaces y tolerantes a errores que los que se suelen usar de forma local, y el mantenimiento de un equipo específico puede realizarse en cualquier momento. Aunque los datos se protegen a través de la redundancia, pueden producirse errores relacionados con la conexión.

Capacidad de los recursos

Las bases de datos de una aplicación se suelen hospedar en sus propios equipos sin compartir hardware con las bases de datos de otras aplicaciones.

Un único equipo hospeda hasta cientos de bases de datos y cada una puede ser de distintas aplicaciones y compartirá los recursos del equipo. La lógica del servicio pasa las bases de datos a diferentes equipos host para expandir horizontalmente la carga global del servicio y permitir la imparcialidad de los recursos.

Con la incorporación de Base de datos Premium, ahora se puede reservar un cierto nivel de capacidad para una Base de datos SQL de Windows Azure. Al reservar una cantidad fija de capacidad para Base de datos SQL y sus réplicas secundarias, la edición Premium ofrecerá un rendimiento más predecible para las aplicaciones en la nube en comparación con las ediciones Web y Business existentes de Base de datos SQL.

Las bases de datos Premium también reducen considerablemente los problemas multiinquilino en comparación con otras ediciones de Base de datos SQL.

Dados los ejemplos anteriores, ¿cuáles son los motivos más comunes para crear las aplicaciones con la Base de datos SQL o pasarlas a ella?

  • Elasticidad. Deseamos obtener acceso a la capacidad más rápidamente y dedicar capital al hardware.

  • Baja sobrecarga de administración. La mayor capacidad de administración se integra en la Base de datos SQL. Y lo que es más importante, basta con ejecutar CREATE DATABASE para proporcionar de inmediato una base de datos de alta disponibilidad que abarca 3 o 4 réplicas en distintos equipos físicos de diferentes bastidores.

  • Precio. Deseamos ofrecer nuestro servicio con un costo menor.

Aunque la información anterior abarca conceptos de alto nivel en lugar de las diferencias fundamentales de la funcionalidad básica de RDBMS, estos conceptos son básicos para saber cómo se comportará el motor de base de datos subyacente y, por tanto, es importante tenerlos en cuenta al diseñar la aplicación.

Es importante entender cómo tomar las decisiones correctas en el diseño de las aplicaciones para aminorar los problemas y conseguir las máximas ventajas del uso de la Base de datos SQL.

Mientras que una aplicación típica de SQL Server puede colocar todo lo asociado a una aplicación en una base de datos (potencialmente grande), una aplicación de Base de datos SQL de Windows Azure típica funciona mejor si las características principales de una aplicación se dividen en bases de datos independientes. Las bases de datos independientes aprovechan los recursos de varios equipos en lugar de uno y este método simplifica la división de las funciones de trabajo de una sola aplicación en varias bases de datos a medida que crecen.

A continuación, el uso del modelo de mantenimiento y hardware de servicio de la Base de datos SQL implica que debe generar comandos en previsión de que algunas operaciones den error y tengan que volver a intentarse. Esto requiere meditar cómo dividir las operaciones en fragmentos menores, evitando un estado temporal duradero y permitiendo que las operaciones puedan reiniciarse con facilidad. Este modelo de programación permite a las aplicaciones seguir trabajando si un servidor de bases de datos conmuta por error en medio de la ejecución del programa.

Las aplicaciones basadas en la Base de datos SQL también utilizan varios enfoques para la solución de problemas y el registro. Al igual que los servidores web, el modelo para solucionar problemas en estas aplicaciones es más conveniente para el registro que para la solución de problemas activa (la consulta de DMV directamente, etc.). Estas secuencias de registros después se convierten en parte de la administración de la aplicación, alimentando los paneles que muestran las partes de una aplicación que están en buen estado o que requieren atención. Cuando se implementa, este modelo habilita aplicaciones a mayor escala con menos trabajo a través de una mayor automatización.

La latencia es otro aspecto importante que hay que considerar en aplicaciones de Base de datos SQL. Dado que algunas partes de la aplicación no son locales hospedadas para los usuarios, esto suele requerir a menudo patrones asincrónicos de ejecución y de cola para que la aplicación responda mejor. En otros casos, es necesario que las aplicaciones consideren cómo tomar decisiones más deliberadas sobre cuántas operaciones de ida y vuelta se necesitan para completar una operación cuando se comparan con una aplicación local equivalente de SQL Server. Estas diferencias se muestran como diferentes patrones y áreas de interés al desarrollar una aplicación para destacar en la Base de datos SQL.

Finalmente, es mejor probar el rendimiento de una aplicación hospedada en el mismo hardware de producción en el que se ejecutará, pero los detalles de la prueba de rendimiento en el hardware compartido y hospedado son diferentes a los de un conjunto dedicado de equipos. Esto se explica con más detalle en la sección 5 de este documento.

Al diseñar una aplicación, hay cuatro opciones básicas disponibles para hospedar la parte de SQL de la aplicación:

  1. SQL Server en la plataforma pura (es decir, sin virtualizar)

  2. SQL Server en la máquina virtual local y hospedada

  3. SQL Server en una máquina virtual de Windows Azure

  4. Base de datos SQL de Windows Azure

Al pasar de las alternativas 1 a la 4 en orden, hay un movimiento claro hacia el ahorro de costos en OPEX y COGS, pero hay una posibilidad reducida de solucionar los problemas de rendimiento utilizando técnicas de ampliación vertical como el hardware especializado así como características relacionadas con el rendimiento específicas de SQL Server. Si los problemas de rendimiento se encuentran en un entorno virtualizado, como Base de datos SQL, tienen que solucionarse a través de los cambios en la aplicación en lugar de incrementando el hardware. Algunos ejemplos de cambios de las aplicaciones son la implementación de algún tipo de modelo de implementación escalada o la clasificación de las diversas tareas de aplicación en depósitos en los que algunas tienen que recibir más recursos y ser ejecutadas de forma sincrónica (una transacción bancaria, por ejemplo) y otras tareas pueden estar en la cola así como ejecutarse con menos recursos (un ejemplo podría ser enviar mensajes de correo electrónico de resumen de la cuenta a los clientes del banco).

La última década se ha centrado en facilitar a los programadores la creación de aplicaciones a través de la incorporación y la amplia adopción de tecnologías como Mapeadores relacionales de objetos (Entity Framework, Hibernate, NHibernate, etc.). Aunque tecnologías como estas crean una solución más rápida de implementar, también resumen las tareas básicas que la base de datos realiza y el impacto que estas tienen en el rendimiento y la escala aparte del desarrollador. Antes de la aparición de la nube, cuando el porcentaje típico de uso del centro de datos solía ser bajo, inferior a la decena, incluso las aplicaciones muy usadas integradas en estas tecnologías que ejecutan llamadas a bases de datos sin optimizar sobreviven simplemente debido al suministro masivo de hardware.

En la última década, el costo real que supone ejecutar una aplicación se ha ocultado, en gran medida, al desarrollador; el desarrollador promedio no necesita preocuparse por ello. Cuando se pide a los principales clientes su punto de vista sobre el costo de la ejecución de las aplicaciones, sobresale un patrón. Por supuesto, estos clientes suelen saber cuánto gastan en sistemas grandes como su ERP principal, pero los cientos de otras aplicaciones que ejecutan y mantienen caen en el apartado de “otras aplicaciones”. Contabilizan el costo total de estas aplicaciones simplemente tomando el costo total de sus aplicaciones y restando el costo de las principales (como el sistema ERP); los detalles sobre el costo de una única aplicación existen en raras ocasiones.

Puesto que muchos clientes no conocen el costo de una única aplicación, el conocimiento de este costo sin especificar pocas veces se da en el equipo de desarrollo que mantiene la aplicación. En este entorno, los desarrolladores tienen pocos incentivos para reducir el costo operativo de la aplicación. Windows Azure cambia esta noción completamente dado que una factura del proveedor de la nube puede dividirse entre el costo de las máquinas virtuales individuales de Windows Azure, los roles web y de trabajo, y la Base de datos SQL que ejecutan una aplicación específica.

Esto no solo es una cuenta; armados con este conocimiento, los negocios tienen la información que pueden utilizar para tomar las decisiones relacionadas con la opción adecuada para solucionar los problemas de rendimiento de la aplicación. Por ejemplo, un problema de rendimiento se puede resolver de los siguientes modos:

  • aumentando los recursos disponibles en Windows Azure para las bases de datos y los roles de trabajo de la aplicación

  • usando la opción Edición Premium para reservar recursos como CPU, E/S de disco y Memoria.

  • rediseñando la aplicación para reducir el consumo facturado de los recursos

  • pasándolo al hardware personalizado de compra y local

Conclusiones

Es importante trasladar a los desarrolladores al modo de pensar de la nube del TCO de aplicación = costo de desarrollo + costo de servicio. A veces, la opción adecuada es invertir en el desarrollo de aplicaciones para reducir el costo del servicio, mientras que otras veces en cambio se puede aumentar el tiempo de los recursos de la aplicación. Esta opción también se puede ver afectada por los conocimientos adicionales de la organización y la escala del problema que tengan que solucionar. Si hay un gran conocimiento sobre el desarrollo de aplicaciones, la decisión de implementar cambios en las aplicaciones para reducir la demanda de recursos de la aplicación puede ser fácil, mientras que en otros escenarios puede ser una opción mejor invertir en usar más recursos disponibles en la plataforma para lograr los objetivos de rendimiento requeridos.

Para ejecutar aplicaciones eficazmente, es importante entender el uso de la aplicación de cualquier servicio en la nube a través de la telemetría. En Windows Azure sugerimos evaluar las grandes herramientas de terceros como New Relic u Opstera, pero también merece la pena considerar soluciones personalizadas basadas en Diagnósticos de Windows Azure. Finalmente, cuidar que la abstracción no genere demasiada complejidad, como en el caso de ORM anterior, puede conducirle a un sistema en el que los problemas de escalabilidad o de rendimiento sean demasiado difíciles o costosos de solucionar.

En esta sección se explicarán los factores comunes que afectan al rendimiento de las operaciones de base de datos. La primera subdivisión abarca los factores tradicionales utilizados en SQL Server. Tenga en cuenta que la mayoría se siguen aplicando a la Base de datos SQL. En la segunda sección se tratan las razones nuevas en la Base de datos SQL. Finalmente, examinaremos el área expuesta de las herramientas de diagnóstico y solución de problemas que la Base de datos SQL de Windows Azure proporciona y usaremos un ejemplo práctico para mostrarle cómo se pueden emplear.

El análisis de rendimiento de SQL Server tiene una larga historia, esta sección debería servir de ayuda para entender los fundamentos. Para obtener más detalles, vea:http://msdn.microsoft.com/es-es/library/dd672789(v=SQL.100).aspx

El Optimizador de consultas de SQL Server toma decisiones de plan que afectan al rendimiento del sistema. Por ejemplo, el optimizador puede decidir realizar una búsqueda de índices o un recorrido de tabla para satisfacer una consulta determinada. Las opciones del optimizador normalmente son correctas, pero hay casos en los que la opción puede ser incorrecta bien porque los datos de entrada (como las estadísticas) están obsoletos o bien si una consulta se encuentra con una limitación del modelo en el Optimizador (como no razonar sobre el sesgo de datos a través de combinaciones en todos los casos en los que se calcule la cardinalidad).

El optimizador puede hacer malas elecciones de planes individualmente (afectando a una sola consulta) o en combinación (donde el rendimiento global del sistema es poco óptimo debido a un conjunto de opciones del plan). El optimizador, más que la heurística básica del espacio de búsqueda entre planes, no se considera optimización a través del plan.

Para obtener más información sobre el Optimizador, haga referencia al capítulo correspondiente en SQL Server 2008 Internals (de Conor Cunningham y otros) o en el próximo documento SQL Server 2012 Internals.

SQL Server se ejecuta en el hardware del usuario, así que es responsabilidad del administrador comprarlo y configurarlo. Si el cliente no instala y configura el hardware correctamente, esto puede reducir el rendimiento del sistema. Algunos ejemplos comunes son:

  • Elección y versión del controlador para diversos componentes (como controladores de disco) que estén mal configurados

  • Configuración BIOS

  • Configuración de la afinidad de la CPU y de NUMA

  • Configuración de la memoria (max server memory, etc.)

  • Intervalos del punto de comprobación

  • MAXDOP

Esta situación se suele tratar con una documentación precisa y pruebas previas de la aceptación del nuevo hardware a fin de validar todas las funciones básicas del sistema (con herramientas como SQLIOSim http://www.microsoft.com/es-es/download/details.aspx?id=20163)

El bloqueo se utiliza para permitir que varios usuarios realicen cambios coherentes a los mismos datos en una forma controlada. Aunque es una parte necesaria de un sistema de base de datos, todos los bloqueos no se crean igual. Por ejemplo, el optimizador puede crear planes para varias consultas que entran en conflicto, ralentizando el rendimiento del sistema global en comparación con otras posibles opciones de plan. En ocasiones, el optimizador puede crear combinaciones de planes que pueden ocasionar interbloqueos (por ejemplo, cuando varios bloqueos se adquieren en orden opuesto a través de dos o más planes). Diferentes opciones de plan (o patrones de llamadas de carga de trabajo) a menudo son necesarias para abordar este tipo de escenario.

El bloqueo temporal es similar al bloqueo en que adjudica acceso multiusuario a las estructuras de SQL Server. Sin embargo, el bloqueo temporal se ocupa de las estructuras internas de las páginas físicas. El bloqueo temporal es en cierto modo ortogonal al bloqueo, pero ambos problemas pueden darse y la resolución básica suele ser similar: si hay un bloqueo temporal activo, la respuesta típica consiste en cambiar el modelo de llamada (aplicando diferentes formas de plan o reorganizando el código de llamada) para mitigar el impacto del bloqueo temporal en el rendimiento total.

Aunque el bloqueo no es un problema de las operaciones multiusuario en una base de datos, sigue siendo posible que el rendimiento se reduzca porque se deniegan los recursos necesarios a algunas operaciones mientras que otros tienen más de los suficientes. Aunque la primera manifestación de esta condición es una operación que tarda más tiempo de lo habitual, la causa interna es que uno o varios recursos sufren la presión. Los factores comunes son el tipo de espera SOS_SCHEDULER_YIELD (que indica que la operación espera en la CPU para llegar a liberarse), largas esperas de E/S (que indican que SQL Server está generando solicitudes de E/S más rápidamente de lo que el sistema de E/S puede procesarlas) y RESOURCE_SEMAPHORE(memoria). Una técnica común para tratar el problema de bloqueo es adquirir solo un equipo mayor o componentes más rápidos.

El punto de comprobación es el proceso mediante el cual DBMS vacía las páginas desfasadas de la memoria en el disco para minimizar el tiempo que la recuperación tardaría si el servidor de bases de datos se bloqueara. Este proceso puede producir un pico en las operaciones de E/S que puede reducir el rendimiento de las consultas y afectar tanto a la latencia como al rendimiento. La carga de las aplicaciones normalmente tendrían que probarse durante un período mayor que la frecuencia del punto de comprobación para que el impacto de este se pudiera medir e incluirse en el planeamiento y la certificación de la capacidad.

noteNota
Observe que SQL Server 2012 contiene una función denominada “punto de comprobación indirecto” (para obtener más información, vea http://msdn.microsoft.com/es-es/library/ms189573.aspx#IndirectChkpt) que puede reducir la sobrecarga de E/S puntual de los puntos de comprobación extendiendo la carga de E/S del punto de comprobación más uniformemente durante un período de tiempo más largo. Esto puede reducir el impacto de E/S en la solución de problemas de rendimiento y de capacidad.

Solo como reafirmación: debe quedar claro que la Base de datos SQL de Windows Azure no es idéntica a SQL Server. La Base de datos SQL es un servicio hospedado que se ejecuta en un centro de datos diferente. Es una aplicación de varios inquilinos, lo que significa que los clientes comparten el mismo equipo físico. Contiene características automáticas como copias de seguridad automáticas y alta disponibilidad automática (HA). Se ejecuta en hardware estándar en lugar de en servidores grandes. Como servicio, se vende a los clientes como tal en lugar de como una licencia. Todos estos factores afectan al modelo empresarial completo de la Base de datos SQL así como a la forma en que se considera el rendimiento y la escala.

Además, la Base de datos SQL no ofrece actualmente diversas características de las consultas del Almacenamiento de datos que muy usadas (lo que significa que el enfoque inicial de la Base de datos SQL está en los sistemas OLTP). Estas características incluyen la compresión de bases de datos, consultas en paralelo, índices ColumnStore y particiones de tabla, junto con compatibilidad con el tamaño de base de datos total y el subsistema de E/S orientados a una carga de trabajo de almacenamiento de datos. Aunque actualmente es posible crear soluciones de almacenamiento de datos con la Base de datos SQL, tenga en cuenta que las diferencias de estas características afectarán a las comparaciones con SQL Server.

En esta sección se explica cómo afecta cada uno de estos factores importantes a la solución de problemas de rendimiento en la Base de datos SQL y se supondrá que los clientes se centran en soluciones OLTP.

Una de las diferencias principales de SQL Server es que la Base de datos SQL expone un servicio de varios inquilinos. Cada equipo físico puede tener cientos (o más) de bases de datos de usuario almacenados en un equipo. Esto permite que la Base de datos SQL permita ofrecer un precio muy bajo (a partir de pocos dólares al mes en Estados Unidos). Esta diferencia es importante: de forma predeterminada, la Base de datos SQL tiene varios usuarios que comparten los recursos de un único equipo en un clúster e intentan equilibrar la carga completa del clúster pasando los clientes a distintos equipos dentro de un clúster para maximizar la imparcialidad y el equilibrio de carga.

Por tanto, un cliente que ejecuta una prueba de rendimiento en su base de datos hospedada puede ejecutarse en un sistema que contenga muchas otras bases de datos activas de otros usuarios. Al igual que en SQL Server normal, hacer que otros clientes usen el mismo hardware afecta a los resultados de las pruebas de rendimiento. Por tanto, debe procurar no realizar conclusiones finales acerca del rendimiento de la Base de datos SQL basándose en una única prueba de rendimiento ya que otros usuarios pueden demostrar que dichas conclusiones no son válidas.

No obstante, tiene la posibilidad de reservar recursos para las bases de datos y las réplicas mediante la opción Edición Premium. De esta forma, tendrá una cantidad de CPU, E/S de disco y memoria garantizada reservada para su base de datos. También puede usar esta opción cuando sea necesario si se actualiza a una Edición Premium y realiza una degradación a una edición Business o Web cuando ya no sea necesaria esa capacidad.

El uso de la base de datos Premium elimina aquellos casos en los que la variación de rendimiento puede hacer que las consultas pequeñas tarden más tiempo del esperado en operaciones sensibles a la latencia. También permite migrar algunas aplicaciones locales sin necesidad de realizar cambios significativos, ya que es una experiencia más próxima a la experiencia aislada tradicional que se daba por supuesto en esas aplicaciones. Para obtener más información, vea Instrucciones sobre la vista previa Premium de Base de datos SQL de Windows Azure.

La Base de datos SQL se genera utilizando clústeres grandes de equipos. Individualmente, estos equipos no son masivos, son equipos de servidor estándar basados en bastidor que maximizan el equilibrio entre el precio y el rendimiento en lugar de basarse solamente en el rendimiento global. Esta diferencia es importante, ya que muchas aplicaciones de SQL Server se crean a partir de la suposición de que ejecutan en un equipo que es “suficientemente rápido o suficiente para” (lo que significa que los clientes comprarían un equipo mayor si alguna vez se quedaran sin recursos al ejecutar la aplicación). La Base de datos SQL no ofrece hardware muy puntero en su oferta hospedada. En su lugar, se trata de un modelo de “ampliación horizontal” en lugar de un modelo de “ampliación vertical”. Cuando una aplicación cliente supera los límites de un único equipo, la expectativa es que el cliente reescribirá la base de datos para utilizar varias bases de datos (en varios equipos) en lugar de un único equipo.

El hardware estándar también sufre problemas mucho antes que las soluciones locales tradicionales. El hardware no tiene fuentes de alimentación redundantes, memoria ECC u otras características para maximizar su tiempo de actividad en todos los casos. Además, hay varios equipos que componen el clúster que tienen que trabajar conjuntamente para aportar una solución completa, tanto en la capa de datos como en la de aplicación. El SLA actual de la Base de datos SQL es que una base de datos estará disponible un 99,9 % del tiempo. Es decir, la instancia promedio de la Base de datos SQL puede no estar disponible durante 42 minutos al mes y seguir cumpliendo ese objetivo. Aunque no todas las bases de datos alcanzan realmente ese objetivo, las cifras globales de disponibilidad de la mayoría de las bases de datos sí lo cumplen. Esto suele ser inferior que en un sistema tradicional de SQL Server. Muchos usuarios de SQL Server no miden formalmente su tiempo de inactividad, pero a menudo se planean eventos de tiempo de inactividad y se envían notificaciones. Los errores de la Base de datos SQL son más aleatorios puesto que suelen ser imprevistos desde la perspectiva de la aplicación. Este tiempo de inactividad implica que el diseño de la aplicación debe tener en cuenta el tiempo de inactividad de cada base de datos en una solución utilizando técnicas que eviten los puntos de error (centrándose en hacer desaparecer los desencadenantes más importantes que siempre dependen de que una sola base de datos esté “activa"), como es caching en otras capas cuando convenga y usar lógica de reintento en la conexión y comandos para conseguir flexibilidad ante los errores de la aplicación y el servicio.

Los servicios o soluciones mayores deben separar formalmente cada función en una o más bases de datos independientes. Por ejemplo, si un servicio tiene una característica que envía el correo a los clientes para realizar el registro para el servicio, puede ser necesario aislar los datos para esta capacidad de otros datos del servicio e incluso expandir los datos de correo en varias bases de datos para controlar la mayor carga (si supera la capacidad de un único equipo). No es improbable tener varios conjuntos distintos de bases de datos, cada una atendiendo una función básica diferente, para administrar los límites de la capacidad de equipos tanto en cuanto a su tamaño como a su disponibilidad.

Puesto que existen diferencias fundamentales en el modo en que las soluciones grandes se diseñan en Windows Azure, la definición de “rendimiento” que se usa para evaluar las soluciones de SQL Server requiere un ajuste. Si una solución de SQL Server funcionaba mejor antes de adquirir una SAN, las cifras de rendimiento para la latencia de E/S pueden no ser tan buenas cuando no tenga una en la Base de datos SQL. Aunque, con frecuencia, la mayor parte de los mismos requisitos empresariales se pueden cumplir sin ningún problema, no debe evaluar el rendimiento neto del hardware como método para determinar si la Base de datos SQL puede resolver un problema empresarial determinado. El hardware es más lento, pero a menudo puede utilizar varios equipos diferentes para obtener el mismo resultado empresarial con los objetivos de rendimiento deseados.

La Base de datos SQL no contiene exactamente el mismo conjunto de características que SQL Server. Las instancias de la Base de datos SQL son conceptos programáticos: representan una base de datos lógica, en lugar de una instancia concreta en un servidor, por ejemplo. Además, algunas características de SQL Server se han bloqueado de la superficie de programación de la Base de datos SQL. En este momento, la Base de datos SQL no expone grupos de archivos o particiones dentro de las bases de datos, por ejemplo, ya que no es necesario para los paradigmas estándar de programación de la Base de datos SQL. Además, algunos casos de usos relacionados con el almacenamiento de datos avanzado (índices ColumnStore) tampoco se exponen en este momento. Estas diferencias habilitan las innovaciones de la Base de datos SQL relacionadas con el modelo de hospedaje y la mayor parte de estas ventajas para el cliente se ofrecerán más adelante a través de otros métodos en la Base de datos SQL.

La Base de datos SQL también pretende reducir los costos laborales asociados a la ejecución, la administración y la optimización de las bases de datos. Como parte de este objetivo, incluye mecanismos automáticos para ocuparse de algunas de las tareas más habituales pero cuyo desempeño perfecto resulta complicado, como son:

  • Copias de seguridad de la base de datos (realizada cada pocos minutos para cada base de datos activa)

  • Alta disponibilidad (la Base de datos SQL ofrece esto con al menos tres réplicas para cada base de datos sin intervención por parte del usuario)

  • Comprobaciones de la coherencia de la base de datos

  • Actualizaciones automáticas: la Base de datos SQL implementará automáticamente nuevas versiones del servicio de un modo en gran parte transparente.

Estas diferencias implican que hay cierta parte de la capacidad de cada equipo que se reserva para realizar estas operaciones. Esto afecta a los métodos que se pueden utilizar para determinar los límites del rendimiento máximo para un sistema, lo que se describe a continuación. Formalmente, la definición de los objetivos de rendimiento para cada operación empresarial contribuye a aislar las evaluaciones de rendimiento de la repercusión de estos mecanismos automáticos.

Windows Azure permite crear servicios expuestos a Internet de gran tamaño. Aunque esto no es exclusivo de Windows Azure, la experiencia necesaria para crear una solución con SQL Server solía restringir este tipo de aplicación a quienes tienen posibilidades económicas y enormes deseos de utilizarla. Esas soluciones de tecnología avanzada a menudo también llevarían a cabo procedimientos para reducir o eliminar el tiempo de inactividad de su solución o servicio diseñando el código para evitar desmontar bases de datos u otros componentes. Por ejemplo, una solución sin tiempo de inactividad incluiría una solución de alta disponibilidad (HA) como la creación de reflejo de la base de datos o Always-On para evitar errores de hardware y para llevar a cabo actualizaciones, por ejemplo que los servidores estuvieran inactivos solo mínimas cantidades de tiempo. Este enfoque es esencial para las soluciones basadas en Base de datos SQL dado que una fracción mayor de las aplicaciones son servicios y un nuevo conjunto de clientes intenta crear tales soluciones totalmente en línea en esta nueva plataforma.

La Base de datos SQL ya proporciona una alta disponibilidad integrada en la solución básica. El tiempo de inactividad debido a las actualizaciones internas del servicio de Base de datos SQL se controla con la misma lógica de reintentos que se utiliza para controlar los errores relacionados con el uso de hardware estándar. Los servicios al cliente, sin embargo, también deben considerar cómo llevar a cabo el proceso de actualización a través de los diversos niveles de una aplicación. Por ejemplo, si un servicio incluye una capa de aplicación o web por encima de una capa de datos, en las actualizaciones suele usarse la técnica siguiente:

  • Implemente nuevos procedimientos almacenados en paralelo con los procedimientos almacenados existentes (sp_createaccount_v1, sp_createaccount_v2)

  • Actualice los equipos de la capa de aplicación (usando la técnica de “intercambio VIP” en Windows Azure) para cambiar a la nueva versión de la aplicación. La actualización en contexto es otra opción en caso de que el intercambio VIP tuviera un impacto en los servicios interrelacionados (por ejemplo, la memoria caché).

  • Agote el trabajo existente en la versión “v1” de los procedimientos almacenados

  • Cuando se complete todo el trabajo anterior, implemente otro cambio que quite las versiones “v1” de los procedimientos almacenados

De hecho, las actualizaciones de la aplicación pueden realizarse en línea descomponiendo la actualización de la aplicación en pasos pequeños que pueden realizarse sin incurrir en tiempo de inactividad. Si algunos pasos requieren tiempo de inactividad, cada trabajo debe llevarse a cabo para reducir ese tiempo programándolos para un pequeño número de clientes internos a la vez (durante las horas en las que no hagan nada) o copiando los datos de usuario a una base de datos nueva en segundo plano de forma que nunca vean el servicio completo como “inactivo”.

Este ajuste mental requiere algunos cambios en las prácticas de ingeniería, pero la descomposición también permite considerar soluciones como desactivar solo parte de un servicio para las actualizaciones en lugar de todo el sistema. Por ejemplo, es posible que pueda deshabilitar la lógica que muestra a los clientes sus facturas de meses anteriores mientras se mantiene el servicio principal activo y en ejecución durante una operación de actualización. La descomposición necesaria para controlar el uso de hardware estándar también ofrece la posibilidad de volver a definir y minimizar el impacto del tiempo de inactividad visible para el cliente con mayor precisión.

Los clientes necesitan determinar si los objetivos de rendimiento se deben cumplir durante los ciclos de actualización. Si esa sí, el servicio o aplicación debe suministrarse para controlar cualquier carga o interrupción adicional ocasionada por la propia implementación del servicio.

Muchos clientes implementan SQL Server y el resto de los componentes de una solución en una subred local, lo que significa que la latencia de red entre las capas a menudo es insignificante. Cuando se pasa una solución a la infraestructura hospedada, puede agregarse latencia entre el cliente y una parte de la solución. Además, las diversas capas de Windows Azure no van a estar en la misma subred de la red, por lo que habrá alguna pequeña diferencia de latencia entre las dos capas. Puede resultar que las soluciones de SQL Server que son muy “locuaces” (hacen muchas pequeñas consultas o actualizaciones) se ejecutan más lentamente en la Base de datos SQL debido a las diferencias de la red física. Para quienes conozcan la informática cliente-servidor anterior, las mismas soluciones se aplican aquí: medite concienzudamente sobre las operaciones de ida y vuelta entre las capas de una solución para controlar cualquier diferencia visible en la latencia.

A continuación se muestran dos métodos prácticos para medir el efecto de esta latencia:

  • Implemente una aplicación sencilla de rol de trabajo o web que ejecuta continuamente una consulta “SELECT 1" en una instancia de la Base de datos SQL de Windows Azure y realiza el seguimiento del comienzo y de los tiempos de respuesta.

  • El Escritorio remoto en esa instancia de rol de trabajo o web de la instancia y ejecute el applet del Monitor de recursos. En la pestaña Red encontrará una cuadrícula “Conexión TCP” con una columna “Latencia (ms)” que proporciona una idea de la latencia en las conexiones con la Base de datos SQL (puede encontrar la dirección IP del servidor virtual de la Base de datos SQL de Windows Azure si ejecuta ping o tracert con el nombre completo y busca en las conexiones al puerto 1433).

Para obtener una descripción completa de las prácticas recomendadas y las optimizaciones relacionadas con la latencia, consulte lo siguiente en el artículo de Guía de Windows Azure: Consideraciones sobre el rendimiento con Base de datos SQL de Windows Azure.

Finalmente, a veces hay problemas dentro del propio servicio de Base de datos SQL que pueden afectar al modo en que se hace el análisis del rendimiento. Este problema es que la Base de datos SQL no expone todas las características que existen en SQL Server. Algunas características que faltan en la Base de datos SQL de Windows Azure (por ejemplo, SQL Profiler) suelen usarse para solucionar problemas de rendimiento de SQL Server en local. Este vacío en la característica es resultado del cambio del área expuesta de programación para exponer las bases de datos en lugar de los servidores como el concepto principal en el servicio de la Base de datos SQL. En la mayoría de los casos, el equipo de SQL prevé ofrecer la misma funcionalidad o una equivalente en fases para abordar tales limitaciones.

El otro problema que puede existir es que la Base de datos SQL en sí misma puede tener errores. Aunque los clientes de SQL Server tienen su propia copia del software, se comparte en la Base de datos SQL. Puede que haya un error en nuestro software y el equipo SQL puede necesitar mitigar un problema o bloquear una característica hasta que este se resuelva. El equipo de SQL diseña las características para ayudar a que este proceso sea más visible y administrable para los clientes en nuestro servicio. Debido a las posibles diferencias entre el diverso comportamiento del funcionamiento de los clústeres de la Base de datos SQL en cualquier momento, es mejor evaluar el rendimiento de un modo que pueda ejecutarse en momentos diferentes y en distintos centros de datos para ayudar a aislar a los clientes de cualquier limitación temporal del servicio. Estos ajustes quitarán la mayoría de dichos factores para que no afecten a las conclusiones extraídas de una única prueba del servicio.

Esta sección describe las técnicas recomendadas para validar y optimizar una solución para la Base de datos SQL así como algunas técnicas específicas.

Dadas las variaciones de la plataforma, no tiene sentido realizar comparaciones pormenorizadas con la Base de datos SQL: el hardware es diferente y la plataforma tiene diferencias que sugieren un enfoque distinto. Al migrar las soluciones existentes, los clientes realizan el máximo progreso en la plataforma utilizando las técnicas que determinan qué rendimiento se necesita para las operaciones básicas y después valorando cómo ajustar el código para cumplir esos requisitos.

Considere el ejemplo siguiente:

Un cliente tiene una aplicación local ASP.NET que hace 10 llamadas a una base de datos de SQL Server local y representa una página en 2 segundos. Se está considerando trasladar esta aplicación web a Windows Azure con un rol de trabajo de la capa de aplicación o web y con la Base de datos SQL como base de datos. Inicialmente, el cliente decide mover solo la aplicación y compilarla. Después de emplear varias horas en solucionar diversos problemas para conseguir implementarla en Windows Azure, observan que la página web tarda ahora 4 segundos en representarse (2 segundos más que antes). El cliente concluye que la nube debe ser “lenta”.

Hay varios factores probables que pueden explicar esta diferencia de latencia (todos los ejemplos específicos se han extraído de los puntos mencionados antes en este tema):

  • Puede haber latencia entre el servidor web y el autor de la llamada (el autor de la llamada está lejos del centro de datos y tarda en que la solicitud viaje a través de Internet)

  • Puede haber una pequeña latencia adicional agregada para cada llamada SQL de la aplicación ASP.NET porque las dos capas no están en la misma subred

  • Los equipos utilizados localmente pueden ser diferentes de los que utiliza la Base de datos SQL

  • Los planes de consulta pueden ser diferentes

Una vez más, la cuestión más importante es que no debe intentar comparar el rendimiento de SQL Server y de la Base de datos SQL para ninguna solución existente: muchas razones por las que puede diferir. Céntrese directamente en la pregunta importante: ¿qué nivel de rendimiento se requiere para solucionar el problema empresarial? En este caso, si el requisito es que la página web se represente para el cliente en dos segundos, hay varias maneras de que se pueda conseguir en la plataforma Windows Azure (la solución exacta puede diferir, sin embargo, entre una solución local de SQL Server, una solución de máquinas virtuales de Windows Azure (IaaS) y la Base de datos SQL). Los posibles cambios que hay que tener en cuenta en este ejemplo para mejorar el rendimiento se relacionan con el segundo objetivo:

  • Determine la latencia entre el cliente y el servidor web (cree una página web de prueba y mida el tiempo de respuesta de una página web que no necesite ponerse en contacto con una base de datos). Si esto es un factor importante, considere buscar un centro de datos más cercano para reducir la latencia o usar una red de distribución de contenido (CDN) para reducir la latencia percibida mediante caching del contenido más próximo a cada usuario.

  • Considere si es posible combinar las operaciones de ida y vuelta de la aplicación ASP.NET para reducir la sobrecarga de la red física asociada entre las capas. Esto puede mejorar la latencia ligeramente.

  • Examine la hora para ejecutar cada consulta y busque los planes de consulta lentos que puedan mejorarse y bloquee los que se puedan eliminar, o busque los recursos de la base de datos que puedan aumentarse. Si fuera necesario, defina los objetivos de rendimiento para cada operación y repita la técnica en cada problema.

  • Determine hasta qué grado puede someter a un esfuerzo a la base de datos antes de conseguir que se limite (busque en los nuevos DMV sys.event_log y sys.database_connection_stats, en la base de datos maestra) para saber si necesita tener en cuenta:

    • Reducir el número de conexiones del nivel de aplicación

    • Escalar el modelo de datos agregando varias bases de datos para obtener el nivel de rendimiento que necesita

La clave es comenzar por el problema empresarial y definir los objetivos en lugar de intentar determinar si la Base de datos SQL tiene el mismo rendimiento que SQL Server; ciertamente, serán diferentes.

Cuando encuentra un problema de rendimiento, suele ser útil intentar aislarlo del resto de orígenes de la varianza y uso de los recursos. Continuando con el ejemplo anterior, supongamos que una consulta concreta finalizó contabilizando 3 segundos de tiempo total. Saque la consulta y ejecútela directamente en la base de datos (quizás desde dentro de un procedimiento almacenado invocado desde SQL Server Management Studio) para aislarla de la solución original. Quizás la aplicación web esté mal configurada de algún modo o la consulta tenga un plan deficiente. Si se ejecutan pruebas aisladas, se eliminan las posibles causas y se ayuda a aislar rápidamente los problemas clave que se van a solucionar. En ocasiones, puede incluso tener sentido considerar esa operación que se está ejecutando mal y apartarla (por ejemplo, quitando elementos clave del texto de una consulta) para averiguar el punto en el que el problema de rendimiento deja de producirse y cuándo la operación vuelve a agilizarse. Esta técnica suele usarla el equipo del producto de SQL al ayudar a los clientes a aislar problemas. Agregar la configuración SET STATISTICS IO ON y SET STATISTICS TIME ON en el nivel de conexión puede contribuir a proporcionar detalles adicionales sobre el rendimiento de la ejecución.

Los problemas de la infraestructura hospedada pueden resultar más difíciles de solucionar. No es posible ver directamente los contadores de rendimiento u otros datos disponibles en las implementaciones locales. Poder realizar una prueba repetible con el registro (quizás almacenado en una base de datos diferente para no afectar a los resultados) es muy útil porque la prueba se puede implementar en diferentes centros de datos. Aunque el hardware que se utiliza en cada centro de datos hoy es similar en gran medida, hay algunas diferencias y pueden aparecer en pruebas específicas, especialmente para un escenario de cliente con exigentes requisitos de latencia en una operación específica. Una vez que determine que una operación dada es esencial, debe validar ese ejemplo aislado en cada centro de datos donde esté previsto que la aplicación se implemente. No todos los clientes tienen un conjunto de evaluación formal de rendimiento y este paso también puede ayudar a las validaciones locales.

En entornos aislados, no siempre es necesario considerar el rendimiento de una operación a través de varias ejecuciones. Los entornos compartidos pueden tener una mayor variación debido a las operaciones del sistema en segundo plano así como al impacto de otros inquilinos del sistema. Por tanto, resulta útil realizar pruebas repetibles y ejecutarlas varias veces. Con frecuencia, al recopilar los resultados de varias ejecuciones, se mostrará alguna diferencia en el rendimiento a través de las llamadas y puede analizarlas creando un gráfico de la distribución del percentil para una operación repetida determinada.

Considere el ejemplo siguiente:

Una consulta de cliente tiene un requisito de latencia deseado para una operación de 20 ms y al ejecutar la consulta 1000 veces, el cliente observa que el promedio es de 26,95 ms. Examinando la distribución del percentil de la latencia a través de todas las llamadas, los datos son como los siguientes:

Porcentaje de distribución de latencia

(El eje X es el percentil para una prueba especificada para ejecutar la misma consulta N veces. El eje Y es la latencia en milisegundos).

Interesante es que la distribución de datos no es uniforme: un pico grande en el extremo superior del conjunto de datos. Debe tener claro que mirar solo según el promedio puede resultar engañoso. Muchas curvas de respuesta de latencia son exponenciales y puede describirlas escogiendo algunos puntos clave a lo largo de la curva y describiendo la latencia en percentiles clave:

 

Promedio

26.95 ms

Percentil 50

15 ms

Percentil 95

21 ms

Percentil 99

80 ms

Percentil 99,9

1044 ms

En este ejemplo, el mayor problema aparece en la cola de la distribución de datos. Hay un punto de datos ocasional que está lejos, mucho peor que los otros. Poder capturar y describir el problema de esta manera ayudará a explicar que no se da en el caso normal: es un problema con algunas situaciones importantes pero poco habituales.

Este ejemplo dado puede suceder en entornos compartidos y se suele relacionar con un paquete TCP descartado en uno de los enrutadores a lo largo de la ruta de acceso utilizada en la solución. Si se descarta el paquete, a la larga TCP reintentará la operación después de un segundo. En este caso, la causa probable de este problema es la congestión de la red. Si este problema aparece con una frecuencia significativamente superior, podría implicar que hay un problema con el hardware de red (lo que significa debe ponerse en contacto con el soporte técnico de Microsoft) o quizás haya algún otro problema que afecta a los resultados.

Debe utilizar el registro de datos y después las estadísticas que caracterizan la distribución para aislar los problemas y decidir entonces si son fundamentales para la empresa. Esta área de análisis es un problema real (aunque el ejemplo anterior se creó para mostrarlo). Si ha habido problemas como este con clientes reales, algunos terminan pasando por alto las situaciones anómalas (lo que significa que no es importante para su empresa y solo cambian sus requisitos para centrarse en el tiempo del percentil 50 en lugar de en el promedio), mientras que en otros casos (al trabajar en instalaciones locales) han reemplazado el hardware para corregir los problemas reales que se encuentran en los enrutadores de red usando esta técnica una vez que el problema se aisló.

De la misma forma que la arquitectura y el enfoque de desarrollo tienen que ajustarse a este entorno en la nube, la mentalidad operativa también tiene que cambiar. Implementar un sistema eficaz de Base de datos SQL de Windows Azure requiere procesos operativos que estén adaptados para el entorno en la nube. Las técnicas y el enfoque tradicionales usados para obtener una visión general de la eficacia y del uso de los recursos y para detectar los errores tiene que modificarse y volver a evaluarse para garantizar que son eficaces a la hora de tomar decisiones operativas en un entorno de varios inquilinos.

Esta sección abarcar varios ejemplos prácticos de técnicas que se pueden usar en una Base de datos SQL de Windows Azure para obtener una visión general operativa. Utiliza ejemplos prácticos con los que investigar, aislar y resolver los problemas reales del cliente y describe las herramientas disponibles y cómo utilizarlas.

La Base de datos SQL expone varias vistas de administración dinámica (DMV) que se pueden utilizar para entender el consumo de los recursos y para identificar las condiciones de error.

El método recomendado es:

  • Identificar los consumidores de recursos: use vistas de administración dinámica de base de datos para identificar los principales consumidores de los recursos y supervise la ejecución de las consultas y la eficacia (por ejemplo, mediante sys.dm_exec_query_stats y sys.dm_db_missing_index_details)

  • Utilizar un método delta: realice periódicamente instantáneas de las solicitudes actuales que se ejecutan en la Base de datos SQL para comprobar el bloqueo, el bloqueo provisional y otros problemas de contención (por ejemplo, con sys.dm_exec_requests)

  • Supervisar los errores: supervise las vistas de administración dinámica de la base de datos maestra para buscar temas relacionados con la conexión como la limitación (por ejemplo, mediante sys.event_log y sys.database_connection_stats)

  • Supervisar el consumo de recursos de la base de datos: supervise la DMV sys.resource_stats para examinar el consumo de recursos de la base de datos a lo largo del tiempo.

Parte de las vistas de administración dinámica mantienen la información acumulada desde la última vez que la Base de datos SQL de Windows Azure principal se movió (un ejemplo es sys.dm_exec_query_stats). Otras contienen una instantánea de un momento dado (sys.dm_exec_requests). El rendimiento de una consulta se ve afectado por la disponibilidad de los recursos, la simultaneidad en los nodos principal y secundario en los que la instancia de la Base de datos SQL reside en ese instante en el tiempo, así como por los problemas de la aplicación como el bloqueo. En el entorno local, sys.dm_os_wait_stats se utiliza normalmente junto con sys.dm_exec_query_stats para entender las restricciones de los recursos y del rendimiento de las consultas, lo que puede deducirse de la información de espera del sistema. sys.dm_db_wait_stats proporciona una vista agregada de todas las esperas encontradas por los subprocesos ejecutados durante las operaciones. Por ejemplo, las esperas de bloqueo indican contención de datos por parte de las consultas y las esperas de bloqueos temporales de E/S de páginas indican tiempos de respuesta de E/S bajos.

Otra técnica también es posible:

  • Realice una instantánea inicial de las estadísticas de consulta al principio del período de supervisión. Registre esto en una tabla temporal o en una tabla física.

  • Realice instantáneas periódicas de las solicitudes de exec durante el período de supervisión.

  • Tome una segunda instantánea de las estadísticas de consultas.

  • Compare la diferencia entre las instantáneas y use la información de las solicitudes de exec para saber si el bloqueo o las esperas de recursos afectaron al rendimiento de las consultas.

Instantánea de resultados de una consulta

Un cliente tenía un problema en el que el cliente experimentaba solicitudes de usuario lentas de una aplicación web que llamaba a una Base de datos SQL de Windows Azure.

El script siguiente identifica los lotes principales que se ejecutan en la instancia de la Base de datos SQL. Este ejemplo muestra los pedidos por el tiempo total de CPU para identificar la consulta que más usa la CPU. El mismo patrón de consulta, con orden según diferentes atributos, puede buscar otros grandes consumidores de cada clase de recurso (E/S lógicas, tiempo transcurrido, etc.). En muchos sistemas transaccionales, los primeros resultados superiores son coherentes (por ejemplo, los principales consumidores globales de CPU también usan la mayoría de los recursos de E/S).

/* Top batches by total CPU time No execution plan
**************************************/
SELECT TOP(25)
SUBSTRING (st.text,1, 512),
SUM(qs.total_worker_time) AS total_cpu_time, 
SUM(qs.total_elapsed_time) AS total_elapsed_time,
CAST((CAST(SUM(qs.total_worker_time) AS decimal) / cast(SUM(qs.total_elapsed_time) AS decimal) * 100) AS int)  AS cpu_vs_elapsed_percentage,
SUM(qs.execution_count) AS total_execution_count,
SUM(qs.total_worker_time)/SUM(qs.execution_count) AS average_cpu_time,
SUM(qs.total_elapsed_time)/SUM(qs.execution_count) AS average_elapsed_time,
SUM(qs.total_logical_reads) AStotal_logical_reads,
SUM(qs.total_logical_reads)/SUM(qs.execution_count) AS average_logical_reads,
SUM(qs.total_logical_writes) AS total_logical_writes,
COUNT(*) AS number_of_statements,
qs.plan_handle,
db_name(st.dbid) AS  [database name],
st.objectid
FROM sys.dm_exec_query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS st
GROUP BY st.text, qs.plan_handle, db_name(st.dbid), st.objectid
ORDER BY SUM(qs.total_worker_time) DESC
   

En este ejemplo, el procedimiento almacenado dbo.spGetTranslationTable utiliza la CPU más de 42 veces lo que el siguiente lote.

Resultados de la consulta

Para determinar el uso de los recursos y la eficacia de una consulta determinada, una técnica común es ejecutarla en aislamiento con SQL Server Management Studio (SSMS). Las opciones SET STATISTICS IO y TIME se pueden usar para proporcionar información útil y también puede obtenerse el plan de ejecución real. Esto se ilustra a continuación:

SET STATISTICS IO ON;
SET STATISTICS TIME ON;
exe [dbo].[spGetTranslationTable] @lang='en'
Resultados de la consulta.

En este ejemplo, la consulta usó 900 lecturas lógicas de la tabla de traducciones. Examinando el plan de consulta, es resultado de un examen del índice clúster de traducciones devolver un subconjunto relativamente pequeño de filas. Al crear el nuevo índice de la tabla se redujo las E/S lógicas y se resolvió el problema.

Resultados de la consulta.

sys.dm_exec_requests proporciona datos sobre el rendimiento de las consultas, como los tipos de bloqueo y de espera. (Para obtener una consulta de ejemplo, vea la Instantánea de sys.dm_exec_requests con WAIT TYPE y WAIT TIME en la sección del apéndice a continuación). En la Base de datos SQL se han implementado algunos tipos de espera nuevos adicionales para representar la funcionalidad específica de la Base de datos SQL. Los tipos de espera SE_REPL_SLOW_SECONDARY_THROTTLE y SE_REPLY_COMMIT_ACK están relacionados con el mecanismo de replicación del registro que la Base de datos SQL usa para cumplir su objetivo de disponibilidad y proporcionar elasticidad. Si estas esperas están presentes en los resultados de la vista de administración dinámica, a menudo indica que hay demasiadas operaciones de E/S a través del canal de replicación. Algunos procedimientos para mitigarlas son:

  • Minimizar las operaciones DML

  • Administrar el tamaño de las transacciones y la inserción por lotes de aplicación

  • Reducir el número total de inserciones de aplicación

  • Administrar las operaciones de base de datos como un mantenimiento de índices minucioso

TipSugerencia
Si los períodos sostenidos de bloqueo SE_REPL afectan significativamente a una aplicación, póngase en contacto con el servicio de soporte técnico de Microsoft para obtener ayuda.

Si la carga en una base de datos hace que las esperas SE_REPL o si la base de datos está limitada por Windows Azure, hay varias opciones. Con cargas de trabajo con muchas escrituras, considere aplicar particionamiento o sharding a los datos para dividirlos en varias bases de datos. Esto reduce tanto la carga en un nodo del sistema como el riesgo de que un solo equipo de base de datos pueda experimentar una situación en la que el límite o el bloqueo puedan afectar a toda la aplicación. En el caso de cargas de trabajo con muchas lecturas, considere el uso de una tecnología de caché distribuida (como Caching de Windows Azure) para almacenar en memoria caché la información de la base de datos y la consulta para ella con menor frecuencia.

Captura de pantalla que muestra SE_REPL_SLOW_SECONDARY_THROTTLE:

Resultados de la consulta.

Captura de pantalla que muestra SE_REPL_COMMIT_ACK:

Resultados de la consulta.

El área expuesta de la Base de datos SQL de Windows Azure continuamente se está ampliando para proporcionar DMV adicionales y otra información para la solución de problemas. Estas DMV relacionadas con índices se han habilitado en la Base de datos SQL:

  • sys.dm_db_index_usage_stats

  • sys.dm_db_missing_index_details

  • sys.dm_db_missing_index_group_stats

  • sys.dm_db_missing_index_groups

La consulta mostrada en la sección Análisis de los índices que faltan (en el apéndice, a continuación) identifica recomendaciones de índices que faltan en gran parte de la misma forma que se interactuaría con SQL Server. Esta información también está disponible en el plan de ejecución que puede obtener de la memoria caché del plan o a través de SSMS. Las capturas de pantalla siguientes ilustran esto.

Resultados de la consulta.

Resultados de la consulta.

Cada Base de datos SQL es un miembro de un servidor virtual (es decir, el servidor lógico). Este servidor lógico tiene una base de datos maestra, que ahora se ha mejorado para proporcionar las DMV sys.event_log y sys.database_connection_stats. La vista sys.database_connection_stats proporciona un resumen del número de conexiones TDS que son correctas, se han terminado o han sido limitadas en una ventana agregada de cinco minutos. La vista sys.event_log proporciona más información sobre las conexiones de la Base de datos SQL así como los errores de conexión, los interbloqueos y los eventos de limitación. Estas DMV permiten solucionar rápidamente los problemas de conectividad de la aplicación.

Resultados de la consulta.

Para obtener más información, vea:

http://blogs.msdn.com/b/wayneb/archive/2012/11/02/introducing-sys-database-connection-stats-for-troubleshooting-windows-azure-sql-database.aspx

http://blogs.msdn.com/b/windowsazure/archive/2012/11/05/announcing-new-dynamic-management-views-for-windows-azure-sql-database.aspx

La DMV sys.resource_stats proporciona una vista del consumo de recursos a lo largo del tiempo. Esta DMV se puede utilizar para investigar el uso de recursos y para planear la capacidad de la aplicación.

Consulta para devolver toda la información de la DMV sys.resource_stats durante los últimos siete días:

SELECT * FROM sys.resource_stats
WHERE  database_name = 'MyTestDB' AND start_time > DATEADD(day, -7, GETDATE())

Capturas de pantalla de los resultados devueltos:

Sys.Resource_Stats

Consulta para devolver el uso de recursos promedio y máximo para una base de datos durante los últimos siete días:

SELECT 
    avg(avg_cpu_cores_used) AS 'Average CPU Cores Used',
    max(avg_cpu_cores_used) AS 'Maximum CPU Cores Used',
    avg(avg_physical_read_iops + avg_physical_write_iops) AS 'Average Physical IOPS',
    max(avg_physical_read_iops + avg_physical_write_iops) AS 'Maximum Physical IOPS',
    avg(active_memory_used_kb / (1024.0 * 1024.0)) AS 'Average Memory Used in GB',
    max(active_memory_used_kb / (1024.0 * 1024.0)) AS 'Maximum Memory Used in GB',
    avg(active_session_count) AS 'Average # of Sessions',
    max(active_session_count) AS 'Maximum # of Sessions',
    avg(active_worker_count) AS 'Average # of Workers',
    max(active_worker_count) AS 'Maximum # of Workers'
FROM sys.resource_stats 
WHERE  database_name = 'MyTestDB' AND start_time > DATEADD(day, -7, GETDATE())

Captura de pantalla de los resultados devueltos:

Sys.Resource_Stats

Consulta para determinar el uso de más de un núcleo:

SELECT
(SELECT
    SUM(DATEDIFF(minute, start_time, end_time))
    FROM sys.resource_stats
    WHERE database_name = 'MyTestDB' AND 
          start_time > DATEADD(day, -7, GETDATE()) AND
          avg_cpu_cores_used > 1.0) * 1.0 / SUM(DATEDIFF(minute, start_time, end_time)
) AS percenage_more_than_1_core
FROM sys.resource_stats
WHERE database_name = 'MyTestDB' AND start_time > DATEADD(day, -7, GETDATE())

Captura de pantalla de los resultados devueltos:

Sys.Resource_Stats

Las consultas que se abarcan en esta sección se pueden utilizar para solucionar problemas y buscar los límites de una sola base de datos.

/* Top statements by total CPU time w/ query plan on the statement level 
note - can be expensive to run this 
**requires** statement_level_query_plan.sql
************************************************************************/
SELECT TOP(25)
SUBSTRING(qt.text,qs.statement_start_offset/2, 
(CASE WHEN qs.statement_end_offset = -1 
THEN len(convert(nvarchar(max), qt.text)) * 2 
ELSE qs.statement_end_offset END -qs.statement_start_offset)/2) 
AS statement_text,
SUBSTRING (qt.text , 1, 512) AS batch_text,
qs.total_worker_time,
qs.total_elapsed_time,
CAST((CAST(qs.total_worker_time AS decimal) / cast(qs.total_elapsed_time AS decimal) * 100) AS int)  AS cpu_vs_elapsed_percentage,
qs.total_worker_time/qs.execution_count AS average_cpu_time,
qs.total_elapsed_time/qs.execution_count AS average_elapsed_time,
qs.total_logical_reads,
qs.execution_count, 
qs.total_logical_reads/qs.execution_count AS average_logical_reads,
db_name(qt.dbid) AS [database name],
qt.objectid,
pln.statement_plan
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt
CROSS APPLY master.dbo.statement_level_query_plan(plan_handle) AS pln
WHERE statement_text LIKE
'%' + REPLACE(LEFT(SUBSTRING((select text from master.sys.dm_exec_sql_text(sql_handle)), 
statement_start_offset/2, 1 + CASE WHEN statement_end_offset = -1 
THEN LEN((SELECT text FROM master.sys.dm_exec_sql_text(sql_handle))) - statement_start_offset/2
ELSE statement_end_offset/2 - statement_start_offset/2 
END) 
,3000), '[','[[]') + '%'
ORDER BY qs.total_worker_time DESC  

-- TOP 50 Query Plans in SQL Azure Database
SELECT TOP(50)
            CONVERT(bigint, DATEPART(yyyy,getdate())*10000000000)+(DATEPART(mm,getdate())*100000000)+(DATEPART(dd,GETDATE())*1000000)+(DATEPART(hh,GETDATE())*10000)+(DATEPART(mi,GETDATE())*100)+(DATEPART(ss,GETDATE())) AS timestampKey ,
                GETDATE() AS eventdateUTC,
            CONVERT(decimal(8,2),(CAST(qs.execution_count AS FLOAT)/(DATEDIFF(mi,qs.creation_time,qs.last_execution_time)+1))*(((CAST(qs.total_worker_time AS FLOAT) / qs.execution_count) / 100000.00)+((CAST(qs.total_elapsed_time AS float) / qs.execution_count) / 1000000.00))) AS Weighting,
            query_plan.value('declare default element namespace "http://schemas.microsoft.com/sqlserver/2004/07/showplan"; 
                            (/ShowPlanXML//Object/@Index)[1]', 'varchar(255)') AS IndexName, 
            qp.query_plan,
                    CASE WHEN query_plan.exist('
                        declare default element namespace "http://schemas.microsoft.com/sqlserver/2004/07/showplan"; 
                        /ShowPlanXML/BatchSequence/Batch/Statements//RelOp/@PhysicalOp[. = "Hash Match"]'
                               )=1 THEN 1 ELSE 0 END AS hash_match
                    , CASE WHEN query_plan.exist('
                        declare default element namespace "http://schemas.microsoft.com/sqlserver/2004/07/showplan"; 
                        /ShowPlanXML/BatchSequence/Batch/Statements//RelOp/@PhysicalOp[. = "Table Scan"]'
                               )=1 THEN 1 ELSE 0 END AS table_scan
                    , CASE WHEN query_plan.exist('
                        declare default element namespace "http://schemas.microsoft.com/sqlserver/2004/07/showplan"; 
                        /ShowPlanXML/BatchSequence/Batch/Statements//RelOp/@PhysicalOp[. = "Clustered Index Scan"]'
                               )=1 THEN 1 ELSE 0 END AS clustered_index_scan
            ,SUBSTRING(qt.text,qs.statement_start_offset/2+1, 
            (CASE WHEN qs.statement_end_offset = -1 
            THEN LEN(CONVERT(nvarchar(max), qt.text)) * 2 
            ELSE qs.statement_end_offset END -qs.statement_start_offset)/2) 
            AS statement_text,
            qs.total_worker_time/qs.execution_count AS average_cpu_time,
            qs.total_elapsed_time/qs.execution_count AS average_elapsed_time,
            qs.total_logical_reads/qs.execution_count AS average_logical_reads,
            qs.total_logical_writes/qs.execution_count AS average_logical_writes,
            qs.execution_count,
            qs.plan_generation_num,
            qs.total_worker_time,
            qs.total_elapsed_time,
            qs.total_logical_reads,
            qs.total_logical_writes,
            db_name() AS [db_name],
            qt.objectid,
            qs.query_hash, 
            qs.creation_time,
            qs.last_execution_time
            FROM sys.dm_exec_query_stats qs
            CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt
            CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) AS qp
            WHERE qt.text NOT LIKE '%sys.%'
            ORDER BY qs.total_elapsed_time DESC

-- Snapshot of current sys.dm_exec_requests with WAIT TYPE and WAIT TIME
declare @i int = 0
                    DECLARE @Requests TABLE (
                    [timestampKey] [bigint] NULL,
                    [eventdateUTC] [datetime] NOT NULL,
                    [statement_text] [nvarchar](max) NULL,
                    [command] [nvarchar](32) NOT NULL,
                    [cpu_time] [int] NOT NULL,
                    [total_elapsed_time] [int] NOT NULL,
                    [wait_type] [nvarchar](60) NULL,
                    [wait_time] [int] NOT NULL,
                    [last_wait_type] [nvarchar](60) NULL,
                    [wait_resource] [nvarchar](60) NOT NULL,
                    [reads] [bigint] NOT NULL,
                    [writes] [bigint] NOT NULL,
                    [logical_reads] [bigint] NOT NULL,
                    [row_count] [bigint] NOT NULL,
                    [granted_query_memory] [int] NOT NULL,
                    [query_hash] [binary](8) NULL,
                    [query_plan] [xml] NULL,
                    [hash_match] [bit] NULL,
                    [table_scan] [bit] NULL,
                    [clustered_index_scan] [bit] NULL,
                    [session_id] [smallint] NOT NULL,
                    [blocking_session_id] [smallint] NULL,
                    [start_time] [datetime] NOT NULL,
                    [status] [nvarchar](30) NOT NULL,
                    [db_name] [nvarchar](128) NULL
                    )

                    WHILE(@i < 20)
                    BEGIN
                    INSERT INTO @Requests
                    SELECT 
                    CONVERT(bigint, datepart(yyyy,getdate())*10000000000)+(datepart(mm,getdate())*100000000)+(datepart(dd,getdate())*1000000)+(datepart(hh,getdate())*10000)+(datepart(mi,getdate())*100)+(datepart(ss,getdate())) as timestampKey ,
                    getdate() as eventdateUTC,
                    SUBSTRING(t.text,r.statement_start_offset/2+1,(case when r.statement_end_offset = -1 then len(convert(nvarchar(max), t.text)) * 2 else r.statement_end_offset end -r.statement_start_offset)/2) as statement_text, 
                    command,
                    cpu_time,
                    total_elapsed_time,
                    wait_type,
                    wait_time,
                    last_wait_type,
                    wait_resource,
                    reads,
                    writes,
                    logical_reads,
                    row_count,
                    granted_query_memory,
                    query_hash,
                    query_plan,
                    case when query_plan.exist('
                        declare default element namespace "http://schemas.microsoft.com/sqlserver/2004/07/showplan"; 
                        /ShowPlanXML/BatchSequence/Batch/Statements//RelOp/@PhysicalOp[. = "Hash Match"]'
                               )=1 then 1 else 0 end as hash_match
                    , case when query_plan.exist('
                        declare default element namespace "http://schemas.microsoft.com/sqlserver/2004/07/showplan"; 
                        /ShowPlanXML/BatchSequence/Batch/Statements//RelOp/@PhysicalOp[. = "Table Scan"]'
                               )=1 then 1 else 0 end as table_scan
                    , case when query_plan.exist('
                        declare default element namespace "http://schemas.microsoft.com/sqlserver/2004/07/showplan"; 
                        /ShowPlanXML/BatchSequence/Batch/Statements//RelOp/@PhysicalOp[. = "Clustered Index Scan"]'
                               )=1 then 1 else 0 end as clustered_index_scan
                    ,session_id,
                    blocking_session_id,
                    start_time,
                    status,
                    db_name() as [db_name] 
                    FROM 
                    sys.dm_exec_requests r
                    cross apply sys.dm_exec_sql_text(r.sql_handle) t
                    cross apply sys.dm_exec_query_plan(r.plan_handle) p
                    WHERE @@spid<>r.session_id
                       waitfor delay '00:00:00:100'
                       set @i = @i+1
                    end
                    select * from @Requests;

-- Missing indexes stats
SELECT  CONVERT(bigint,datepart(yyyy,getdate())*10000000000)+(datepart(mm,getdate())*100000000)+(datepart(dd,getdate())*1000000)+(datepart(hh,getdate())*10000)+(datepart(mi,getdate())*100)+(datepart(ss,getdate())) [timestampKey] 
 ,getdate() [eventdateUTC], 
 db_name() as [db_name], 
 mig.index_group_handle, 
 mid.index_handle,  
 'CREATE INDEX missing_index_' + 
 CONVERT (varchar, mig.index_group_handle) + '_' + 
 CONVERT (varchar, mid.index_handle) + ' ON ' + 
 mid.statement   + ' (' + ISNULL (mid.equality_columns,'') + 
 CASE WHEN mid.equality_columns IS NOT NULL AND mid.inequality_columns IS NOT NULL 
THEN ',' 
ELSE '' 
 END + ISNULL (mid.inequality_columns, '') + ')' + 
 ISNULL (' INCLUDE (' + mid.included_columns + ')', '') 
 AS create_index_statement,  
 migs.*, 
 mid.database_id, 
 mid.[object_id] 
FROM sys.dm_db_missing_index_groups mig 
INNER JOIN sys.dm_db_missing_index_group_stats migs ON migs.group_handle = mig.index_group_handle 
INNER JOIN sys.dm_db_missing_index_details mid ON mig.index_handle = mid.index_handle 
WHERE 
 CONVERT(decimal (28,1), migs.avg_total_user_cost * migs.avg_user_impact * (migs.user_seeks + migs.user_scans)) > 10 
ORDER BY 
 migs.avg_total_user_cost * migs.avg_user_impact * (migs.user_seeks + migs.user_scans) DESC

Vea también

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