indices

Operadores Spool en planes de ejecución

Una de las primeras cosas que hacemos, o por lo menos que deberíamos hacer, cuando estamos analizando el rendimiento de una consulta es mirar su plan de ejecución. En los planes de ejecución vemos paso a paso y gráficamente lo que hace nuestra consulta. Cada uno de estos pasos de los que hablamos está representado gráficamente por un operador y la mayoría son intuitivos y fáciles de comprender pero hay un tipo en concreto que parece que cuesta un poco más. Me refiero como no podía ser de otra manera a los operadores Spool. Estos componentes pueden marcar la diferencia en términos de eficiencia y tiempo de respuesta de las consultas. En este artículo, profundizaremos en los diferentes tipos de Spool, su propósito, cómo funcionan y cuándo deberíamos prestarles atención.

¿Qué es un operador Spool?

Antes de entrar en detalles, es importante entender qué es un operador Spool. Básicamente, son operadores que almacenan temporalmente un conjunto de filas durante la ejecución de una consulta. Este almacenamiento permite que SQL Server reutilice estos datos en lugar de volverlos a calcular o volver a leerlos desde el disco, lo que puede resultar en una mejora significativa del rendimiento en determinadas situaciones. Existen varios tipos de operadores spool en SQL Server y, aunque todos comparten la definición que hemos mencionado, cada uno tiene sus particularidades. 

Table Spool

El «Table Spool» es el tipo de Spool más común en SQL Server. Su objetivo principal es almacenar el resultado de una subconsulta o una parte del plan de ejecución que es probable que se reutilice. Este tipo de operador suele aparecer cuando tenemos consultas que requieren repetir una operación costosa varias veces. Por ejemplo, si una subconsulta se ejecuta en múltiples ocasiones dentro de una misma consulta, SQL Server puede decidir almacenar temporalmente el resultado de esa subconsulta en un Table Spool para evitar esas múltiples ejecuciones.

Un detalle importante a considerar es que, aunque el Table Spool puede reducir el tiempo de ejecución en general, también consume memoria temporal para almacenar los datos, lo que podría impactar en la eficiencia si el tamaño del Spool es considerablemente grande.

Index Spool

El «Index Spool» se utiliza cuando SQL Server anticipa que necesitará un índice temporal para mejorar la búsqueda de datos en una consulta específica. Este operador crea un índice en memoria, que puede ser utilizado para acelerar operaciones como JOINs o búsquedas basadas en condiciones de filtrado. Aunque esta operación añade un paso adicional al plan de ejecución, la creación de un índice temporal puede resultar en un rendimiento significativamente mejorado, especialmente en consultas que trabajan con grandes volúmenes de datos.

La clave para entender el impacto de un Index Spool está en el balance entre el coste de crearlo y los beneficios que aporta en la fase de búsqueda. En escenarios donde se ejecutan varias búsquedas en un conjunto de datos sin un índice adecuado, este operador se convierte en una solución efectiva.

Row Count Spool

El «Row Count Spool» es un tipo de operador que se emplea principalmente para controlar el número de filas que se procesan en una operación. A diferencia de los Spool anteriores, este no almacena datos per se, sino que mantiene un conteo de las filas que pasan a través de él. Este operador suele aparecer en situaciones donde se requiere un número preciso de filas como resultado de una subconsulta, como cuando usamos la cláusula TOP o una condición de filtrado que limita las filas a procesar.

En resumen, este operador actúa como un portero de discoteca que asegura que solo pasen el número exacto de filas necesarias. Es especialmente útil en operaciones que pueden generar un gran número de filas intermedias, pero donde solo se necesita un subconjunto de ellas. Así, el Row Count Spool ayuda a evitar el procesamiento innecesario, optimizando el rendimiento de la consulta.

Window Spool

El «Window Spool» es menos común pero no menos importante. Este tipo de operador se emplea principalmente en consultas que utilizan funciones de ventana, como ROW_NUMBER(), RANK() o LEAD(). El propósito del Window Spool es soportar el cálculo de estas funciones, almacenando temporalmente el conjunto de datos sobre el cual se aplicarán las funciones de ventana.

Las funciones de ventana requieren acceso a un conjunto completo de datos para calcular correctamente sus resultados. El operador Window Spool permite que SQL Server mantenga un «almacén» de estas filas mientras las operaciones de ventana se ejecutan, garantizando así que el resultado sea el esperado. Aunque puede añadir cierta sobrecarga en términos de memoria, su beneficio en la correcta ejecución de funciones analíticas es crucial.

Optimización y uso

Entender cuándo y cómo aparecen los Spool en los planes de ejecución es vital para optimizar el rendimiento de nuestras consultas. Si bien estos operadores pueden mejorar la eficiencia en muchos casos, su uso inadecuado o innecesario puede tener el efecto contrario. Es fundamental analizar los planes de ejecución y evaluar si la presencia de un Spool está realmente justificada en base al coste adicional que implica su utilización.

En algunos casos, podríamos encontrar que la eliminación de un Spool innecesario, ya sea mediante la reescritura de la consulta o ajustando los índices, resulta en un rendimiento superior. También es importante recordar que estos operadores suelen consumir memoria temporal, por lo que su impacto en la carga general del sistema debe ser monitorizado de cerca.

Recursión

Las consultas recursivas son un ejemplo de la necesidad de operadores Spool. En una consulta recursiva típica, SQL Server tiende a utilizar dos tipos de Spool que resultan esenciales para su correcto funcionamiento y optimización: el Table Spool y el Index Spool.

Spool en recursividad

Table Spool en recursividad

Al principio de una consulta recursiva, SQL Server suele emplear un Table Spool. Este operador, como hemos visto, se utiliza para almacenar el conjunto inicial de filas que formarán la base de la recursión, conocido como la parte ancla en un CTE recursivo. La función principal de este operador es capturar estas filas iniciales para que puedan ser reutilizadas a lo largo de las iteraciones recursivas sin necesidad de recalcular o volver a leer los datos desde el origen.

Este Table Spool es especialmente útil en este contexto porque permite que el proceso recursivo se inicie de manera eficiente, asegurando que las filas base estén disponibles para las iteraciones subsiguientes sin añadir un coste significativo de I/O o de CPU. Este operador se convierte en un «almacén temporal» que facilita la generación de los resultados recursivos de manera escalable.

Index Spool en recursividad

En la fase final de la recursión, cuando se procesan y ordenan los resultados, SQL Server suele introducir un Index Spool. Este operador crea un índice temporal en memoria sobre el conjunto de datos generado durante la recursión. La finalidad de este índice es acelerar la búsqueda y ordenación de los datos, especialmente en consultas que requieren un orden específico o que deben cumplir con condiciones adicionales de filtrado.

El Index Spool optimiza la fase de finalización de la consulta recursiva, permitiendo que SQL Server gestione grandes volúmenes de datos generados por la recursión de manera más eficiente. La creación de este índice temporal puede ser costosa en términos de memoria y CPU, pero su impacto positivo en el rendimiento de la consulta suele justificar su utilización, especialmente en estructuras de datos jerárquicas complejas.

Conclusión

Los operadores Spool en SQL Server son herramientas poderosas que, cuando se utilizan correctamente, pueden mejorar significativamente el rendimiento de nuestras consultas. Desde el Table Spool, que almacena datos para evitar cálculos repetidos, hasta el Window Spool, que soporta funciones analíticas, cada tipo de Spool tiene un propósito específico y un impacto en la forma en que SQL Server procesa las consultas.

Para sacar el máximo provecho de los Spool, es esencial comprender cómo y cuándo aparecen en los planes de ejecución y evaluar su eficacia en cada caso. Aunque estos operadores pueden añadir complejidad al plan de ejecución, su correcta utilización puede ser la clave para lograr un rendimiento óptimo en SQL Server.

En definitiva, los Spool no son solo un detalle técnico, sino una pieza fundamental en la optimización avanzada de consultas. Con el conocimiento adecuado, podemos utilizarlos para transformar consultas lentas en operaciones altamente eficientes, maximizando el rendimiento de nuestras bases de datos.

Si tenéis alguna duda o sugerencia, podéis dejarla en Twitter, por mail o dejarnos un mensaje en los comentarios. Y recuerda que también tenemos un grupo de Telegram y un canal de YouTube a los que te puede unir. ¡Hasta la próxima!

Publicado por Roberto Carrancio en Cloud, Rendimiento, SQL Server, 1 comentario

Reducir bases de datos (shrink)

En nuestro pasado artículo hablamos del crecimiento de las bases de datos. Entre otras cosas, os expliqué las diferencias entre espacio utilizado y espacio total del fichero y a que eran debidas. También vimos los errores más comunes que nos pueden llevar a que nuestras bases de datos crezcan más de lo necesario. En el artículo de hoy vamos a ver las técnicas de reducción de espacio de una base de datos con la operación shrink. El objetivo es que entendamos cuándo y por qué usar esta herramienta y si tienes que usarla, al final del artículo te diré cómo.

Espacio ocupado y utilizado

Como explicamos en el pasado artículo, aunque muy por encima, el espacio que ocupan nuestras bases de datos SQL Server en disco no es el tamaño real que tienen ocupado los datos. Por temas de rendimiento, el espacio que se asigna al fichero es mayor, o debería serlo, al que realmente ocupan los datos. Esto es así porque los tiempos de las operaciones de escritura podemos dividirlos en dos, por un lado reservar el espacio necesario en disco para los datos y por último escribir los datos. Aunque con técnicas como la inicialización instantánea de ficheros podemos agilizar mucho el proceso de crecimiento de los ficheros, si el espacio ya está previamente reservado, es decir, ocupado por el fichero pero no utilizado, será mucho más rápido el proceso de escritura. 

Reducir una base de datos

Cuando hablamos de reducir una base de datos, lo único que vamos a poder hacer sin eliminar datos es liberar ese espacio que tenía el fichero reservado pero no en uso. Es decir, reducir el tamaño del fichero hasta como mínimo el tamaño máximo de los datos. En el pasado artículo ya hablamos de las técnicas para que los datos ocupen menos y esto nos puede servir para reducir su tamaño, sin embargo, ninguna de estas técnicas va a reducir por sí misma el tamaño de los ficheros, para eso tenemos que recurrir a una reducción de ficheros o de base de datos también conocida como shrink.

¿Qué es el shrink?

El shrink es un proceso mediante el cual se reduce el tamaño físico de un archivo de base de datos, ya sea de datos o de log. Este comando libera espacio no utilizado y lo devuelve al sistema operativo. Aunque a primera vista puede parecer una herramienta útil para gestionar el espacio en disco, es fundamental entender cómo funciona realmente y los efectos que puede tener en el rendimiento de la base de datos. Empecemos por el principio, podemos hacer un shrink de toda la base de datos o de solo unos ficheros (ya sean de datos o de log), esta última opción es la más recomendable ya que nos permite un mayor control sobre la operación. 

Tipos de Shrink

Por otro lado, existen tres tipos de shrink, debido a que solo se puede liberar el espacio libre al final del fichero nos encontramos con un shrink truncateonly donde solo se libera ese espacio libre al final del fichero pero el espacio que hay entre los datos (fragmentación) sigue ocupado, este tipo de shrink es el más rápido y menos invasivo. 

El tipo más efectivo para liberar espacio es cuando definimos un tamaño que será el tamaño total que ocupe el fichero tras el proceso, en este caso, para conseguir liberar todo el espacio, SQL Server moverá físicamente los datos dentro del fichero eliminando los espacios libres y dejándolos al final para así poder liberar todo ese espacio. Esta operación en ficheros de datos es complicada, no solo por lenta, sino porque desfragmenta los índices. Al mover los datos de sitio los índices ya no apuntan al sitio correcto y hay que reconstruirlos después o no serán usables. El problema con esto, es que al reconstruir los índices, SQL Server crea un nuevo índice y al terminar borra el antiguo y si, durante este proceso vuelve a consumir espacio del fichero de datos. En concreto el espacio que ocupa el índice. 

Por último, cuando tenemos varios ficheros de base de datos del mismo filegroup podemos hacer un shrink en uno de ellos que lo vacíe por completo moviendo los datos al resto de ficheros. Esto también nos va a generar los problemas de fragmentación comentados anteriormente.

Ventajas del Uso del Shrink

Una de las ventajas más obvias del shrink es la liberación de espacio en disco. Esto nos será especialmente útil en situaciones donde el almacenamiento sea limitado o costoso. Además, el shrink puede ser una solución rápida para situaciones de emergencia en las que se necesita liberar espacio inmediatamente. Podemos ejecutar un shrink de forma fácil, incluso podemos programarlo en jobs para que se ejecute automáticamente. Incluso podemos configurar nuestras bases de datos para que liberen el espacio libre por defecto de manera automática.

Otra ventaja es que el shrink puede ayudar en la gestión de archivos de log de transacciones, que a menudo crecen considerablemente en bases de datos con muchas transacciones. En este contexto, el shrink puede reducir el tamaño de estos archivos después de una copia de seguridad del log, evitando así que ocupen espacio innecesario. En este mismo contexto, podemos hacer un shrink sobre la base de datos tempdb cuando haya crecido más de la cuenta debido a una transacción grande.

Inconvenientes y Riesgos del Shrink

A pesar de sus ventajas aparentes, como ya hemos comentado, nos podemos encontrar con muchos inconvenientes si ejecutamos un shrink sin ser cuidadosos. Uno de los principales problemas es la fragmentación de los índices. El proceso de shrink puede reorganizar los datos de manera que los índices queden fragmentados, lo que puede degradar significativamente el rendimiento de las consultas. La fragmentación aumenta el tiempo de respuesta de las consultas y la carga sobre el sistema, lo cual es contraproducente en entornos de alta demanda.

Además, el shrink es un proceso que consume recursos, muchos recursos. Durante su ejecución, puede aumentar la carga de trabajo del servidor, afectando a otras operaciones. Tendremos que tener un especial cuidado en bases de datos grandes o en sistemas con recursos limitados. También es importante mencionar que el espacio liberado por el shrink no se puede recuperar sin expandir el archivo nuevamente, lo cual podría ser necesario si la base de datos vuelve a crecer rápidamente.

Prácticas Recomendadas para el Uso del Shrink

Dado que el shrink puede tener efectos adversos en el rendimiento, es crucial seguir ciertas prácticas recomendadas para minimizar sus desventajas. Primero, no debemos usar el shrink como una solución de gestión de espacio a largo plazo. Normalmente si ya hemos utilizado un espacio vamos a necesitarlo en un futuro. Por tanto, es mejor emplearlo en situaciones específicas, como después de la eliminación masiva de datos o en la gestión de archivos de log de transacciones. Como ya habrás adivinado, cuando hacemos un shrink del log de transacciones o de la tempdb no vamos a vernos afectados por la fragmentación de índices.

También es recomendable realizar el shrink en momentos de baja actividad para minimizar el impacto en el rendimiento del sistema. Posteriormente, deberemos realizar una reconstrucción de índices para solucionar la fragmentación causada por el proceso de shrink. Esto ayuda a restaurar el rendimiento óptimo de las consultas.

Por último, debemos tener una previsión del espacio que van a necesitar nuestros ficheros de bases de datos y reducirlos siempre dejando el suficiente espacio libre para unas escrituras óptimas.

Alternativas al Shrink

El shrink más eficiente es el que no se hace. En este sentido, existen alternativas que pueden ser más adecuadas en ciertas circunstancias. La gestión proactiva del espacio, como la eliminación de datos obsoletos o el archivo de datos antiguos, puede reducir la necesidad de realizar un shrink. Además, la implementación de prácticas de mantenimiento regulares, como el reindexado y la actualización de estadísticas, puede ayudar a mantener la base de datos en buen estado sin los efectos adversos del shrink.

Conclusión

El shrink en SQL Server es una herramienta que debe ser utilizada con precaución y entendimiento. Aunque puede ofrecer una solución rápida para liberar espacio en disco, sus efectos secundarios, como la fragmentación de índices y el consumo de recursos, deben ser cuidadosamente gestionados. Es fundamental considerar el shrink como una herramienta de última instancia y explorar alternativas y prácticas de mantenimiento regulares para mantener una base de datos saludable y eficiente. La clave está en el balance y en la planificación proactiva, asegurando que el rendimiento y la integridad de los datos no se vean comprometidos.

Si has llegado hasta aquí esperando ver cómo hacer un shrink te diré que este no era el objetivo de este artículo, tienes eso en un vídeo aquí. Hoy quería contarte todo lo que rodea a esta operación, para mi, es más importante saber cuándo y por que hacer un shrink que saber hacerlo.

Si tenéis alguna duda o sugerencia, podéis dejarla en Twitter, por mail o dejarnos un mensaje en los comentarios. Y recuerda que también tenemos un grupo de Telegram y un canal de YouTube a los que te puede unir. ¡Hasta la próxima!

No te vayas aun. Hemos creado una página donde estamos recopilando todos estos artículos que dan respuesta a estas preguntas frecuentes de SQL Server. Pásate por aquí a echar un vistazo.

Publicado por Roberto Carrancio en Cloud, Rendimiento, SQL Server, 0 comentarios

¿A qué se debe el crecimiento excesivo de bases de datos?

El crecimiento descontrolado de las bases de datos es una preocupación común para los administradores de sistemas y bases de datos. El aumento natural de los datos puede ser una explicación pero, en ocasiones, este crecimiento puede estar influenciado por errores de modelado, configuraciones inadecuadas y prácticas de gestión poco eficaces. En este artículo, abordaremos algunos errores comunes que contribuyen a este problema y veremos soluciones prácticas para tratar de evitarlo.

Crecimiento normal de los datos

Antes de entrar en detalles sobre cómo controlar el crecimiento de nuestros datos tenemos que dejar clara una cosa. Tu base de datos va a crecer, es el comportamiento común. El crecimiento natural y orgánico de las bases de datos es un fenómeno esperado en cualquier sistema en funcionamiento. A medida que se almacenan más datos, ya sea por la expansión de la empresa, el aumento de las operaciones o la recopilación de información de clientes y transacciones, es normal que las bases de datos crezcan. Este crecimiento, aunque esperado, debe ser gestionado adecuadamente para evitar problemas de rendimiento y costes innecesarios.

Crecimiento por errores de modelado de bases de datos

Una de las áreas fundamentales donde se pueden originar problemas de crecimiento en bases de datos es en el diseño y modelado de la propia base de datos. Errores como la falta de normalización adecuada o la sobrecarga de índices pueden llevar a un uso ineficiente del espacio y un crecimiento innecesario de la base de datos.

Falta de normalización adecuada

Una de las causas más frecuentes del crecimiento innecesario de bases de datos que he podido contemplar a lo largo de los años es una falta de normalización adecuada. La normalización ayuda a minimizar la redundancia de datos y garantiza la integridad referencial. Sin embargo, cuando no se aplica correctamente, puede resultar en la duplicación de datos a lo largo de varias tablas, inflando el tamaño total de la base de datos.

Para ponerle solución, es recomendable revisar el diseño de las bases de datos para asegurar que estén normalizadas correctamente. Aunque en algunas situaciones específicas pueda ser necesario que  desnormalicemos los datos para mejorar el rendimiento, sobre todo en entornos analíticos y de BI, esta decisión debemos tomarla con precaución y basándonos en un análisis sólido de las necesidades de la aplicación.

Sobrecarga de índices

Otro de los errores que más se cometen es el uso excesivo de índices. Es tan común ver bases de datos con índices innecesarios o duplicados como bases de datos sin índices. Este es otro problema que puede contribuir al crecimiento de las bases de datos ya que los índices nonclustered son objetos separados de la tabla que requieren su propio almacenamiento duplicando los datos en cada índice que aparezcan. Aunque los índices son fundamentales para acelerar las consultas, mantener demasiados puede llevar a un aumento innecesario en el tamaño de la base de datos, además de afectar el rendimiento durante las operaciones de inserción, actualización y eliminación.

La solución es sencilla, revisar los índices que no se utilizan y eliminarlos, pero a la vez requiere de conocimientos avanzados tanto de administración como del uso de la base de datos para no eliminar un índice que sí sea importante para el rendimiento. Otra buena práctica es usar índices filtrados cuando sea posible ya que pueden proporcionar beneficios de rendimiento específicos sin un aumento significativo en el espacio de almacenamiento.

Crecimiento por configuraciones inadecuadas en SQL Server

Además del diseño de la base de datos, la configuración del servidor SQL también puede influir significativamente en el tamaño y rendimiento de la base de datos. Configuraciones inadecuadas, como el modo de recuperación FULL sin una correcta gestión de los logs de transacciones, o una configuración incorrecta del tamaño del archivo, pueden provocar un crecimiento inesperado y descontrolado.

Modo de recuperación FULL y log de transacciones

El modo de recuperación FULL es esencial para una recuperación completa en caso de desastres, ya que registra todas las transacciones. Sin embargo, si no se gestionan adecuadamente, los logs de transacciones pueden crecer de forma incontrolada, ocupando mucho espacio en disco. Cuando configuras este modo de recuperación tienes que habilitar una buena política de backups con backup log frecuentes o vas a encontrarte con problemas de crecimiento del log descontrolado.

Como hemos dicho la solución es sencilla en este caso, basta con implementar una estrategia de backups regulares de los logs de transacciones. Esto no solo controla el tamaño del log, sino que también es crucial para la recuperación de datos. Es importante revisar la frecuencia de los backups y ajustar las políticas de recuperación según las necesidades de la organización. Si no es necesario este tipo de copias regulares deberías replantearte el modo de recuperación de tu base de datos.

Configuración inadecuada del tamaño del archivo

Es importante entender la diferencia entre el tamaño del fichero y el tamaño de los datos, ya que esta distinción puede proporcionar una visión más clara sobre cómo se está utilizando el espacio en la base de datos y qué medidas pueden ser necesarias para optimizar su rendimiento y almacenamiento. En SQL Server los archivos de base de datos se dimensionan más allá del tamaño real que tienen ocupado por los datos para que las futuras escrituras sean más rápidas. Este espacio libre en los ficheros es importante, por tanto, para el rendimiento pero hay que saber gestionarlo. Una configuración inicial incorrecta del tamaño de los archivos de datos y logs, junto con opciones de autogrowth mal configuradas, puede resultar en un crecimiento fragmentado y subóptimo de los archivos. Esto puede llevar a un uso ineficiente del espacio en disco y afectar negativamente el rendimiento. 

Para evitar estos problemas debemos configurar adecuadamente el tamaño inicial de los archivos de datos y logs basándonos en las previsiones de crecimiento de la base de datos. Sin embargo, las bases de datos cambian con el tiempo y deberemos ajustar los incrementos de autogrowth para minimizar la fragmentación y asegurar un uso eficiente del espacio en disco.

Crecimiento por errores de aplicación

Los errores en el diseño y configuración no son las únicas fuentes de problemas. Las aplicaciones que interactúan con la base de datos pueden causar un crecimiento descontrolado, especialmente si no gestionan adecuadamente las transacciones o si insertan datos de manera ineficiente. 

Errores de aplicación en la gestión de transacciones

Uno de los errores más comunes que puede llevar al crecimiento descontrolado de los logs de transacciones es el manejo inadecuado de las transacciones por parte de las aplicaciones. Esto incluye transacciones que permanecen abiertas por mucho tiempo o que no se cierran correctamente, lo cual puede causar un aumento innecesario en el tamaño del log.

Debemos revisar y optimizar el código de la aplicación para asegurarnos de que las transacciones se manejen de manera eficiente. Es crucial que las transacciones sean lo más cortas posibles y que se cierren correctamente para evitar el crecimiento innecesario del log. Prestaremos una atención especial a las transacciones de larga duración o aquellas que se producen con demasiada frecuencia.

Errores por insertar datos erróneamente

Otra causa de crecimiento desmedido es la inserción de datos redundantes debido a errores de lógica en la aplicación o a escrituras descontroladas en tablas de log de actividad de las aplicaciones o procesos. Esto puede suceder cuando las aplicaciones insertan datos duplicados debido a fallos en la validación o la falta de controles adecuados para evitar duplicados.

Para evitarlo, deberemos implementar mecanismos de validación en el nivel de la aplicación para prevenir la inserción de datos redundantes. Además, utilizar restricciones de unicidad y primary keys en la base de datos para garantizar la unicidad de los registros. Las tablas de auditoría o de log deberán limpiarse frecuentemente y revisar que la información registrada es útil. Por ejemplo, una buena práctica si un proceso tiene una lógica de reintentos es solo registrar una vez el error y poner una columna con un contador de repeticiones si el error es el mismo en cada reintento.

Evitar el crecimiento con mantenimiento

La gestión y mantenimiento regulares de nuestros datos es fundamental para controlar el tamaño de las bases de datos SQL Server. Esto incluye la limpieza de datos obsoletos y una monitorización constante del rendimiento y el uso del almacenamiento. Sin una gestión adecuada, es fácil que el crecimiento se descontrole, afectando el rendimiento y la eficiencia del sistema.

Limpieza de datos obsoletos

Las bases de datos tienden a acumular datos obsoletos o redundantes que ya no son útiles para la operación actual, contribuyendo al crecimiento desmedido. Esto es especialmente problemático en sistemas que carecen de políticas de limpieza o archivado de datos. Establecer procedimientos regulares de limpieza para eliminar registros obsoletos y/o implementar políticas de retención de datos y archivado que permitan gestionar los datos históricos de manera eficiente, liberará espacio en nuestras bases de datos más activas.

Monitorización y mantenimiento

Para terminar con este artículo, y aunque esto no es un error como tal no quería dejar de comentar que la falta de monitorización y mantenimiento adecuado puede permitir que problemas de crecimiento pasen desapercibidos. Esto incluye no solo el seguimiento del tamaño de los datos y logs, sino también la identificación de problemas de rendimiento que pueden indicar un uso ineficiente de recursos. Utilizar herramientas de monitorización propias o de terceros y establecer alertas ante crecimientos inusuales de bases de datos y logs puede evitarnos el problema de que el servidor termine quedándose sin espacio y deje de admitir nuevas transacciones. 

Conclusión

El crecimiento excesivo de las bases de datos SQL Server a menudo se debe a una combinación de errores de modelado, configuraciones inadecuadas y prácticas de gestión insuficientes. Abordar estos problemas con soluciones prácticas, como la normalización adecuada, la gestión eficiente de índices, y la implementación de políticas de mantenimiento y backups, puede ayudar a controlar el tamaño de la base de datos y asegurar un rendimiento óptimo. Con un enfoque proactivo en estas áreas, seremos capaces de manejar el crecimiento de las bases de datos de manera más efectiva y evitar problemas futuros relacionados con el almacenamiento y el rendimiento.

Si tenéis alguna duda o sugerencia, podéis dejarla en Twitter, por mail o dejarnos un mensaje en los comentarios. Y recuerda que también tenemos un grupo de Telegram y un canal de YouTube a los que te puede unir. ¡Hasta la próxima!

No te vayas aun. Hemos creado una página donde estamos recopilando todos estos artículos que dan respuesta a estas preguntas frecuentes de SQL Server. Pásate por aquí a echar un vistazo. 

Publicado por Roberto Carrancio en Cloud, SQL Server, 1 comentario

SQL vs DAX ¿Quién es más rápido?

El pasado viernes andaba yo absorto en la masterclass de Salvador Ramos en Nasmasdata cuando, de repente, una diapositiva salvaje apareció. Salva nos hablaba de un cálculo de stock acumulado con su fórmula en DAX porque según ponía en SQL era un cálculo imposible. ¿IMPOSIBLE? Eso era un reto para mí, así que, raudo tomé una captura de pantalla y acepté ese reto. No hubo que esperar mucho, hoy sábado, de buena mañana me he sentado delante del ordenador, he creado una tabla con los datos necesarios para la prueba y me he puesto manos a la obra. No sin antes contactar a Salva e informarle de lo que estaba aconteciendo porque sí amigos, Salva sabe de la existencia de este artículo días antes que vosotros, para la próxima que el reto venga de vosotros y estaréis informados antes. 

SQL-vs-DAX_1

Entendiendo el reto en DAX

Lo primero que tenemos que entender es lo que nos propone el reto, la medida DAX que se ve en la imagen es esta:

Por un lado CALCULATE es una función que cambia una expresión en un contexto de filtro modificado. Como parámetros le hemos pasado [Stock Final] que es una medida o una calculada que nos sumariza los movimientos de stock. Para el segundo parámetro hemos pasado la función FILTER con dos parámetros más, el resultado es que filtra la tabla Fecha para incluir solo las filas donde la fecha es menor o igual a la fecha máxima en el contexto actual.

Convirtiendo el DAX a T-SQL

Ahora que ya sabemos lo que tenemos que obtener vamos a ver como debemos hacerlo en SQL Server, a ver si realmente era imposible o no. He de deciros que mi tabla solo tiene dos columnas fecha y stock. Podriamos haber complicado el escenario añadiendo artículos pero para la demo nos vale sin eso, supongamos que tenemos solo uno. Como luego vamos a llevarnos estas tablas a Power BI tal como están en SQL no hay problema, en DAX vamos a jugar en las mismas condiciones.

Para empezar vamos a tener que totalizar por dias para saber cuantos movimientos hemos tenido ese día. Luego tenemos que hacer una suma de los valores desde la primera fecha hasta la fecha actual. Eso lo podremos lograr con una función de ventana. Esta sería la consulta imposible:

Vamos a verla paso a paso. En lo primero que nos tenemos que fijar es en la subconsulta del FROM. Es justo lo que comentábamos antes, la suma de los movimientos de stock agrupados por día. Luego, en la consulta principal, estamos utilizando una función de ventana para calcular el Stock_Acumulado. Esta función de ventana SUM() OVER (ORDER BY Fecha ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) suma los valores de Stock_Final en todas las filas desde el inicio de la tabla (UNBOUNDED PRECEDING) hasta la fila actual (CURRENT ROW), ordenadas por Fecha. Esto da como resultado un total acumulativo de Stock_Final hasta la fecha actual.

SQL-vs-DAX_2

Ya lo tenemos, no era imposible. Sin embargo, a lo que Salva se refería era los inconvenientes de realizar los cálculos en SQL por tiempos. Y realmente este es un pensamiento muy extendido en el sector. DAX es más rápido realizando cálculos que SQL Server. Pero, ¿realmente es cierto? Vamos a verlo.

Comparativas de rendimiento DAX vs SQL

Para que los resultados puedan ser representativos, vamos a hacer las pruebas sobre una tabla con algo más de 1 millón de registros, algo normal en una empresa pequeña. Vamos a analizar dos años de datos de movimientos de stock. Para medir los tiempos de la consulta DAX he sacado la consulta de la tabla y la he llevado a DAX Studio. En SQL vamos a usar las estadísticas de tiempo que podemos sacar con SET STATISTICS TIME ON.

SQL-vs-DAX_3

Como vemos los resultados son demoledores y para nada lo esperado. Analizando 1.010.000 registros repartidos en 1096 fechas distintas SQL Server se ha demorado 85 milisegundos de los cuales 78 ms han sido CPU. En DAX Studio podemos ver que la fórmula DAX para la tabla ha tardado 180 milisegundos, repartidos entre 175 ms del motor de fórmulas (FE) y 5 ms del motor de almacenamiento (SE). 

Complicando el escenario

Vamos a pasar de 1 millón a 15 millones de registros a ver si los resultados son distintos. Todos sabemos que el fuerte de Power BI reside en su motor Vertipaq y su gran capacidad de trabajar con grandes cantidades de datos.

SQL-vs-DAX_4

Ahora sí que vemos la gran diferencia de tiempos de la que todo el mundo habla en DAX y Power BI. Con 15 millones de registros los tiempos en SQL Server se han disparado a 1219 milisegundos de CPU aunque paralelizando la consulta se ha resulto en 186 ms. En DAX tenemos un tiempo total de 193 milisegundos repartidos en 175 ms del motor de fórmulas (FE) y 18 ms del motor de almacenamiento (SE). Aunque los tiempos de DAX son mayores a los de SQL no hay tanta diferencia y teniendo en cuenta el paralelismo de SQL podemos deducir un mayor consumo de recursos si ejecutamos los cálculos en origen.

Mejorando los tiempos de SQL

Ya sabemos el objetivo a batir en DAX 193 ms. Veamos qué podemos hacer en SQL. Para empezar vamos a probar con un índice columnar sobre la tabla, al fin y al cabo los índices columnares son la misma tecnología que el motor vertipaq de Power BI.

SQL-vs-DAX_5

Ahí lo tenemos, ahora sí. Nuestra consulta sobre la tabla con índices columnares ha tardado 155 milisegundos de CPU y solo 56 ms totales al paralelizar. Aun así esto todavía se puede mejorar, ¿recordáis las vistas indexadas? Vamos a probarlo.

SQL-vs-DAX_6

¿Qué os parece el resultado? ¿Os lo esperabais? Con la combinación de índice columnar más vista indexada hemos podido ejecutar la consulta pesada sobre 15 millones de registros en menos de un milisegundo. A mi me ha sorprendido la verdad. No esperaba tanta mejoría.

Es importante destacar que esto es una prueba de concepto en un entorno de laboratorio sin carga de trabajo donde puedo hacer todos los cambios que quiero sobre el SQL sin afectar a ningún otro proceso. Esto es un escenario muy simplificado para la DEMO sin ningún parecido con una base de datos de un ERP de producción. Como siempre digo, primero válida en tus servidores de pruebas y luego, si ves que va bien y no da problemas, piensa en aplicarlo en producción.

Conclusión

SQL sigue más vivo que nunca. Es verdad que DAX es muy potente y seguro que tiene un montón más de optimizaciones de las que yo he sido capaz de aplicar. Os diré que para las pruebas estaba la inteligencia de tiempos desactivada y como dimensión de tiempos estaba usando la plantilla que Salva proporciona gratuitamente en su web que entiendo que es la que usa él. 

Si tenéis alguna duda o sugerencia, podéis dejarla en Twitter, por mail o dejarnos un mensaje en los comentarios. Y recuerda que también tenemos un grupo de Telegram y un canal de YouTube a los que te puede unir. ¡Hasta la próxima!

PD.: Salva, no me importa el resultado de estas pruebas, tu sigues siendo un referente para mi 🙂.

Publicado por Roberto Carrancio en Cloud, Power BI, Rendimiento, SQL Server, 0 comentarios

Detectando fragmentación de índices en SQL Server y Azure

Volvemos a la carga con un artículo sobre índices de esos que tanto nos gustan. Esta vez vamos a hablar de un tema muy importante y es detectar qué índices están más fragmentados y cómo solucionarlo. A menudo vemos que una mala gestión de los planes de mantenimiento provocan una degradación del rendimiento de las consultas y eso, gran parte de las veces es debido a un problema de fragmentación de índices o falta de mantenimiento de las estadísticas. Hoy vamos a centrarnos en el primero de estos aspectos.

¿Cómo detectar fragmentación en los índices?

Para ver la fragmentación de un índice en concreto podemos hacerlo desde el entorno gráfico de nuestro SSMS, haciendo click derecho sobre el objeto y mirando sus propiedades. Sin embargo, esto no es práctico cuando tenemos cientos de índices en nuestra base de datos y queremos saber de un vistazo cuales son los más fragmentados y cuanto. Para ello, usaremos una consulta sobre la función de sistema sys.dm_db_index_physical_stats

Otra de las cosas que debemos tener en cuenta es el tamaño de nuestra tabla, con menos de 1000 páginas, el motor de base de datos directamente ignorará los índices nonclustered y, en el caso de los clustered, tampoco vamos a notar diferencia.

Con esto en mente vamos a preparar el script. 

Revisemos el script, por un lado podemos ver que a la función para ver las estadísticas de los índices le estamos pasando el id de la base de datos actual para que se ejecute en ese contexto. Esto es para evitar que se ejecute por todas las bases de datos y podamos tener un problema de rendimiento con esta consulta. Por otro lado vemos que solo afecta a tablas y vistas de usuario que tengan un índice clustered, el tipo de índice 0 está excluido de los filtros. Las tablas HEAP (sin índice clustered) necesitan otro tipo de tratamiento. Podemos ver también el filtro para solo mostrar índices con más de 1000 páginas y el de fragmentación superior al 5%, que suele considerarse el umbral de fragmentación aceptable.

Solucionar fragmentación de índices

Ahora que sabemos cuales son los índices más fragmentados debemos actuar y solucionar el problema. Sabemos que tenemos a nuestra disposición dos alternativas: reorganizar o reconstruir. Para elegir entre una opción u otra tenemos varios factores a tener en cuenta.

Por un lado tenemos el modo de operación de estas instrucciones, reorganizar siempre es una operación online lo que significa que solo generará sobre nuestro índice un intento de bloqueo compartido. El índice se podrá seguir leyendo durante la reordenación sin causar bloqueos. En cuanto a la reconstrucción, solo es online si se lo especificamos manualmente y eso solo es posible en ediciones Enterprise de SQL Server o en las bases de datos o instancias gestionadas de Azure. Si la reconstrucción es offline se generará un bloqueo exclusivo sobre el índice.

Por otro lado, la reconstrucción es más eficiente que la reorganización para porcentajes elevados de fragmentación y eso deberemos tenerlo también muy en cuenta.

¿Debería reorganizar o reconstruir mis índices con mucha fragmentación?

Esto no es una ciencia exacta y es un tema sobre el que hay muchas opiniones discordantes. Normalmente se habla de reorganizar los índices con una fragmentación superior al 5 o 10% y menor al 15 o 30%. Como veis es una horquilla muy amplia y para atinar tenemos que pensar en las las implicaciones de estas operaciones que ya hemos visto antes. Yo os voy a contar cómo lo hago yo pero esto es totalmente personal y deberás adaptarlo a cada caso.

Escenario 1: Mantenimiento programado

En este primer escenario estamos hablando de un mantenimiento programado dentro de una ventana de mantenimiento en la que no hay interferencia con otros procesos. Este caso es el más sencillo porque no tenemos que pensar en no entorpecer a nadie. En estos casos yo pongo el umbral para empezar a actuar en un 5%. Si estamos hablando de una edición Standard de SQL Server reorganizaré los índices con una fragmentación entre un 5 y un 20% y reconstruiré los de mayor fragmentación. Para ediciones Enterprise o Azure reduciré esa horquilla para reorganizar entre un 5 y un 15% y haré reorganizaciones online a partir del 15%.

Escenario 2: Problema puntual de rendimiento

En este escenario estamos hablando de un momento de carga de trabajo elevada en el que hemos recibido o detectado una incidencia por problemas de rendimiento. Tenemos que actuar rápido para solventar la situación pero entorpeciendo lo menos posible a los procesos de negocio que ya de partida tienen un rendimiento mermado. En estos casos pongo el umbral para empezar a actuar en fragmentaciones por encima del 10% en vez del 5. A partir de ahí, si tenemos la suerte de contar con una edición Enterprise, o estamos en Azure, no hay más problema, reconstruiremos con las mismas condiciones que en el escenario anterior, a partir del 15%. Para una edición Standard, donde si vamos a generar bloqueos si reconstruimos, intentaremos reorganizar hasta el 30% de fragmentación.

Solucionar estadísticas desactualizadas

Las estadísticas son clave para SQL Server. Como ya hemos comentado en este blog muchas veces, unas estadísticas desfasadas pueden tener el mismo impacto negativo o peor que un índice fragmentado. Por este motivo, es importante tenerlas en cuenta a la hora de realizar nuestros mantenimientos o enfrentar una incidencia por degradación de rendimiento. Una reconstrucción de índices siempre actualizará las estadísticas asociadas a ese índice pero en el caso de las reorganizaciones deberemos hacerlo manualmente. Tenemos que contar también con que una actualización de estadísticas es más ligera y rápida que un mantenimiento de índices por lo que, en caso de una degradación de rendimiento de una consulta puntual, yo siempre actualizo las estadísticas de las tablas involucradas como primera medida.

Conclusión

Ante un problema de rendimiento, tenemos que verificar el estado de nuestros índices y estadísticas. Además, consultar su nivel de fragmentación será clave a la hora de decidir si vamos a reorganizarlo o reconstruirlo y, todo esto, siempre sin dejar de lado las estadísticas. Tened en cuenta que por mucho que tengamos implementada una solución de mantenimiento de índices y estadísticas nunca vamos a estar 100% seguros de que no va a haber una variación tal de datos que nos va a generar fragmentación o a dejar desfasadas nuestras estadísticas. Es importante que mantengamos una monitorización y vigilancia continua para garantizar el mejor desempeño de nuestros SQL Server.

Si tenéis alguna duda o sugerencia, podéis dejarla en Twitter, por mail o dejarnos un mensaje en los comentarios. Y recuerda que también tenemos un grupo de LinkedIn y un canal de YouTube a los que te puede unir. ¡Hasta la próxima!

Publicado por Roberto Carrancio en Cloud, Índices, Rendimiento, SQL Server, 1 comentario

Configurar planes de mantenimiento en SQL Server y Azure

Hola a todos y bienvenidos a este nuevo formato de Video Blog que espero que os guste y que podamos ver por aquí más a menudo. Hoy vamos a ver un caso práctico sobre como configurar planes de mantenimiento en nuestro SQL Server o instancia administrada en Azure gracias a los script de Ola Hallengren. En todo este tiempo como DBA (más de 10 años) os aseguro que más del 90% de las incidencias por supuestos problemas de rendimiento a las que me he enfrentado eran siempre por lo mismo, una falta de mantenimiento correcto. Por esto es importante programar tareas de reconstrucción de índices y mantenimiento de estadísticas. Y ya de paso, aprovechamos y configuramos las copias de seguridad y comprobaciones de integridad que también nos ofrece esta solución gratuita. Pocas veces vas a encontrar más por menos.

Guía de capítulos

  • 00:00 Introducción
  • 00:39 Descarga
  • 01:20 Instalación
  • 05:42 Backups
  • 10:15 Integrity Check
  • 11:42 Index Optimize
  • 13:13 Limpieza
  • 13:54 Log de procesos

Configurar planes de mantenimiento

Como podemos ver en el vídeo para descargar los scripts de mantenimiento solo deberemos acudir a la web de Ola Hallengren y descargar el script que se llama «MaintenanceSolution.sql». Con el script ya abierto en nuestro SSMS podremos configurar la base de datos donde se van a crear los scripts y una serie de configuraciones importantes para los jobs.

Una vez instalada la solución de planes de mantenimiento vamos a poder configurar en los distintos jobs las tareas de copias de seguridad, supervisión de la integridad y reconstrucción y actualización de índices y estadísticas para las bases de datos de sistema y de usuario. También es importante que configuremos los trabajos que incluyen las tareas de mantenimiento para no encontrarnos con incidencias de espacio en disco en un futuro.

Esta solución, además, tiene la ventaja de dejar un log bastante completo en una tabla llamada CommandLog que estará en la misma base de datos que hayamos creado los procedimientos almacenados de mantenimiento. En esta tabla podremos encontrar todo el historia de ejecuciones de todos los comandos con su detalle, horas de inicio y de fin y, por supuesto, si ha dado un error veremos el por qué.

Publicado por Roberto Carrancio en Cloud, SQL Server, Videos, 0 comentarios

Claves Foráneas (FK): Trucos, Ventajas e Inconvenientes

En las bases de datos, las claves foráneas (FK) son una herramienta esencial para mantener la integridad referencial entre las tablas. Sin embargo, su uso puede tener tanto ventajas como desventajas, especialmente en términos de rendimiento y consumo de CPU. Tanto es así que por ejemplo MySQL por defecto renuncia a la integridad referencial en pro de la velocidad. Otros SGBD relacionales como SQL Server, PostgreSQL u Oracle sí que tratan las FK como una restricción. Comprender este comportamiento es clave para entender el comportamiento de nuestras bases de datos. Pero, veámoslo con detenimiento.

¿Qué son y cómo funcionan las FK?

Como hemos adelantado en la introducción, las claves foráneas son una forma de garantizar la integridad referencial en nuestras bases de datos. Cuando definimos una FK, estamos creando una relación entre dos tablas, donde una tabla tiene una columna o un conjunto de columnas que hacen referencia a una clave primaria en otra tabla. De esta manera no podremos crear en nuestra tabla destino registros con un valor que no exista previamente en la tabla de referencia.

Pensad en un modelo normalizado donde tenemos una tabla de cabeceras de facturas y en otra tabla las líneas de esas facturas. Una FK entre las tablas nos permitirá no poder tener en la tabla de líneas ningún registro que pertenezca a una factura inexistente. Esto tiene más implicaciones, como por ejemplo que en la tabla de facturas no podamos editar o borrar un dato si tiene líneas asociadas que, de otra manera, quedarían huérfanas. 

Actualización y Borrado en Cascada

Las claves foráneas en SQL Server y otros sistemas permiten configurar acciones de actualización y borrado en cascada. Esto significa que cuando se actualiza o se elimina un registro en la tabla principal, SQL Server automáticamente actualizará o eliminará los registros correspondientes en las tablas relacionadas.

La principal ventaja de la actualización y borrado en cascada es que simplifica la gestión de las bases de datos. No necesitamos escribir código adicional para manejar estas operaciones, ya que SQL Server se encarga de ello por nosotros. Esto puede ahorrar tiempo y reducir la posibilidad de errores.Sin embargo, la actualización y borrado en cascada también tienen sus inconvenientes. Si no se utilizan correctamente, pueden llevar a la eliminación inadvertida de datos. Por lo tanto, es importante utilizar estas características con cuidado y entender completamente sus implicaciones antes de implementarlas.

En resumen, la actualización y borrado en cascada son herramientas poderosas que pueden simplificar la gestión de nuestras bases de datos. Sin embargo, como con cualquier herramienta, deben utilizarse con cuidado y con un entendimiento completo de sus ventajas e inconvenientes.

Ventajas de las FK

Las FK proporcionan varias ventajas. La más importante, como ya hemos visto, es la garantía de la integridad referencial. Esto significa que no podemos tener datos huérfanos en nuestra base de datos. Además, las FK pueden ayudar a mejorar la legibilidad y la organización de nuestra base de datos. Además tienen otra gran ventaja que a menudo pasamos por alto y no es otra que facilitarnos la comprensión del modelo de datos.

Mantenimiento de la Integridad referencial

Las FK garantizan que los datos en las tablas relacionadas siempre sean consistentes. Esto es crucial para evitar anomalías de datos y garantizar la precisión de los resultados de las consultas.

Comprensión del modelo de datos

Las FK simplifican el proceso de entender el modelo de datos, sobre todo cuando nos enfrentamos a él por primera vez y no hay documentación. Al proporcionar conexiones claras entre las tablas es sencillo entender esas relaciones para cualquiera que lo sepa leer.

Inconvenientes de las FK

A pesar de sus ventajas, las FK, como todo, también tienen sus inconvenientes. Como hemos mencionado, pueden afectar al rendimiento y al consumo de CPU y disco. Además, pueden complicar las operaciones de inserción, actualización y eliminación, ya que requieren comprobaciones adicionales.

Rendimiento

El uso de FK puede tener un impacto significativo en el rendimiento y el consumo de CPU y el disco duro de nuestra base de datos. Cuando se inserta, actualiza o elimina un registro en una tabla que tiene una FK, SQL Server debe realizar comprobaciones adicionales en todas las tablas referenciadas para mantener la integridad referencial. Esto puede aumentar el tiempo de ejecución de estas operaciones y, por lo tanto, el consumo de CPU y disco. Personalmente he llegado a operaciones tan simples como un DELETE por la PK de una tabla que, debido a las FK, obliga a SQL Server a leer más de 50 tablas. Tenemos que tener cuidado con esto sobre todo a medida que el modelo de datos crece y las relaciones entre las tablas se complican.

Además, las verificaciones de integridad referencial requieren un procesamiento adicional, lo que puede aumentar el consumo de CPU además del disco duro. En sistemas con una gran cantidad de transacciones, esto puede ser un problema. Recuerda mantener siempre una buena monitorización sobre el rendimiento de tu modelo de datos.

Complejidad de las operaciones de escritura

No solo nos vamos a encontrar con degradaciones en el rendimiento de SQL Server sino que, para nosotros como DBAs y para los administradores de los datos también se va a añadir una capa de complejidad a la hora de trabajar con los datos. Son escenarios muy comunes para un DBA el de restaurar solo los datos de una tabla de la copia de seguridad o el de copiar datos entre distintos entornos. En estos casos, por ejemplo, tendremos que tener muy claro el orden de las inserciones y deberemos hacerlo de manera secuencial para evitar errores. O eso o deshabilitamos temporalmente las FK pero en este caso deberemos validarlas otra vez al activarlas y en tablas grandes eso es inviable. 

Indexar para evitar los inconvenientes de las FK

Como hemos podido ver, el hecho de tener FKs en nuestra base de datos va a añadir una lógica adicional a las transacciones de escritura lo que va a provocar un mayor consumo de recursos y por tanto un peor rendimiento de nuestro SQL Server. En este sentido, el indexado de los campos de las claves foráneas es una práctica esencial que puede mejorar significativamente el rendimiento de nuestras bases de datos. Crear índices para esos campos referenciados por una clave foránea permitirá, que a la hora de actualizar o borrar un registro en la tabla principal, SQL Server pueda usarlos para verificar rápidamente la integridad referencial sin tener que leer completamente la tabla.

Conclusión

Las claves foráneas son una herramienta poderosa en SQL Server pero también es un arma de doble filo. Aunque pueden tener un impacto en el rendimiento y el consumo de CPU, los beneficios que aportan en términos de integridad referencial suelen superar estos costes. Como siempre, la clave está en entender cómo funcionan y usarlas de manera inteligente. Recuerda, cada base de datos es un mundo y lo que funciona en uno puede no funcionar en otro. Por lo tanto, siempre es recomendable probar y monitorizar el rendimiento antes de implementar cualquier cambio a gran escala.

Como siempre, te animo a experimentar con estas técnicas y a explorar todas las posibilidades que ofrecen. Si tenéis alguna duda o sugerencia, podéis dejarla en Twitter, por mail o dejarnos un mensaje en los comentarios. Y recuerda que también tenemos un grupo de LinkedIn y un canal de YouTube a los que te puede unir. ¡Hasta la próxima!

Publicado por Roberto Carrancio en Rendimiento, SQL Server, 1 comentario