Rendimiento

Ciclo de Vida y Niveles de Soporte de SQL Server

En el mundo de la tecnología si hay algo cierto es la constante evolución. Esto es una realidad ineludible como que si un usuario tiene permisos elevados terminará metiéndonos en un lío. Como buenos DBAs profesionales, nos enfrentamos a la tarea de mantenernos al día con las últimas versiones de SQL Server. Ya hablamos aquí de las actualizaciones de SQL Server pero, ¿qué sucede con las versiones antiguas? ¿Cómo gestionamos su ciclo de vida y los niveles de soporte?

Ciclo de Vida de SQL Server

El ciclo de vida de un producto de software se refiere a las diferentes etapas por las que pasa desde su lanzamiento hasta que deja de recibir soporte. En el caso de SQL Server, el ciclo de vida, se divide en dos fases principales: el soporte principal y el soporte extendido.

Soporte Principal

Durante la fase de soporte principal (mainstream), Microsoft ofrece actualizaciones de seguridad, correcciones de errores y nuevas características. Esta fase dura normalmente 5 años desde la fecha de lanzamiento de la versión.

Soporte Extendido

Una vez concluida la fase de soporte principal, entramos en la fase de soporte extendido. Durante este periodo, que también suele durar 5 años, Microsoft sigue ofreciendo actualizaciones de seguridad, pero ya no se añaden nuevas características ni se realizan correcciones de errores no relacionados con la seguridad. Veremos esto más en profundidad ahora con los niveles de soporte.

Niveles de Soporte para las Versiones de SQL Server

Además del ciclo de vida, es importante entender los niveles de soporte que Microsoft ofrece para las diferentes versiones de SQL Server. Los niveles de soporte se refieren al tipo y alcance del soporte técnico que se proporciona durante las diferentes fases del ciclo de vida de un producto de software. En el caso de SQL Server tenemos tres fases principales: soporte total, limitado y fin de soporte.

Soporte Total

Durante la fase de soporte principal, una versión de SQL Server tiene soporte total. Esto significa que se pueden solicitar todas las formas de soporte, incluyendo la resolución de problemas, la corrección de errores y las actualizaciones de seguridad.

Soporte Limitado (extendido)

En la fase de soporte extendido, el nivel de soporte se reduce a soporte limitado. En este nivel, Microsoft solo proporciona actualizaciones de seguridad y ya no se resuelven problemas ni se corrigen errores que no estén relacionados con incidentes de seguridad.

Fin de Soporte

Finalmente, cuando una versión de SQL Server alcanza el fin de su soporte, ya no se proporcionan actualizaciones de seguridad ni soporte técnico. Aunque es cierto que en casos muy extremos y con incidentes de seguridad de máxima gravedad Microsoft puede hacer excepciones, es crucial planificar la migración a una versión soportada antes de llegar a esta fase. Por ejemplo, me viene a la mente la famosa actualización GDR crítica del 14 de febrero de 2023 que salió para todas las versiones de SQL desde 2008 hasta 2022 aunque las versiones de 2008, 2008 R2 y 2012 estaban fuera de ciclo de vida, en fase de fin de soporte. Como digo, son casos muy excepcionales y la recomendación es no mantener servidores cuando estos han alcanzado el fin de soporte.

Actualizaciones de SQL Server

Como ya vimos en un anterior artículo, las actualizaciones de SQL Server pueden ser Service Packs (SP), Cumulative Updates (CU) o General Distribution Releases (GDR). Estas actualizaciones esenciales que Microsoft lanza para las versiones de SQL Server, aunque no alteran el ciclo de vida general de una versión de SQL Server, tienen su propio ciclo de vida y pueden extender el soporte de una versión específica. Veamos caso a caso como influyen.

Service Packs

Un Service Pack (SP) puede extender el ciclo de vida de una versión de SQL Server. Cuando se lanza un SP, este tiene su propio ciclo de vida, que se extiende más allá del ciclo de vida original de la versión principal. Por ejemplo, aunque SQL Server 2014 ha finalizado su ciclo de vida de soporte principal, el soporte extendido para SQL Server 2014 SP3 sigue activo hasta el 9 de julio de 2024. Esto significa que Microsoft continuará proporcionando actualizaciones de seguridad y soporte técnico para SQL Server 2014 SP3 incluso después de que la versión principal haya alcanzado su fin de soporte hace varios años. Aunque Microsoft dejó de publicar SPs a partir de la versión de SQL Server 2016, como sé que sois mentes intrépidas y con sed de datos, os contaré que estas actualizaciones solo se lanzaban para productos en la fase principal del ciclo de vida de un producto.

Cumulative Updates

Las Cumulative Updates (CU), por otro lado, son actualizaciones más frecuentes que incluyen correcciones de errores y mejoras de rendimiento. Microsoft cambió el modelo de SPs por el CUs, más frecuentes y con menos cambios cada una. Digamos que hasta SQL 2016, Microsoft esperaba a tener una gran actualización para liberar un nuevo SP y, ahora, lo que hace es ir liberando pequeñas actualizaciones pero de manera más frecuente. Todo muy agile, ¿verdad? Esto tiene una implicación directa para nosotros y es que, aunque una CU tiene un ciclo de soporte propio de 1 año a partir de su fecha de lanzamiento, no extiende el ciclo de vida de la versión principal de SQL Server como sí hacían los SPs. Al igual que pasaba con los SPs, las CUs solo se liberan durante la fase principal del ciclo de vida de una versión SQL.

General Distribution Releases

Las General Distribution Releases (GDR) son actualizaciones que se centran principalmente en las correcciones de seguridad. A diferencia de los SP y las CU, las GDR no añaden nuevas características ni mejoras de rendimiento. Sin embargo, son críticas para mantener la seguridad de nuestras bases de datos y, al igual que los SP y las CU, tienen su propio ciclo de vida. Con todo lo que ya hemos visto, habréis podido adivinar que las GDR se lanzan durante todo el periodo de ciclo de vida, tanto principal como extendido siendo las únicas actualizaciones de las que dispondremos fuera del ciclo de vida principal de una versión de SQL Server.

Conclusión

Como profesionales de bases de datos, es esencial que comprendamos el ciclo de vida y los niveles de soporte de las versiones de SQL Server. Esto nos permitirá planificar eficazmente las actualizaciones y garantizar que nuestras bases de datos sigan siendo seguras y eficientes. Recuerda, mantenerse al día no es solo una cuestión de aprovechar las nuevas características, sino también de garantizar la seguridad y la estabilidad de nuestros sistemas. Las actualizaciones, tanto SPs, CUs y GDRs juegan un papel crucial en la gestión del ciclo de vida de SQL Server. Es importante tener en cuenta estos detalles al planificar las actualizaciones y el mantenimiento 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 LinkedIn y un canal de YouTube a los que te puede unir. ¡Hasta la próxima!

Publicado por Roberto Carrancio en SQL Server, 0 comentarios

IDENTITY o Secuencias, ¿Cuál es mejor?

Cuando llevas ya un tiempo en el mundo de las bases de datos, especialmente en SQL Server, es normal encontrarnos repetidamente con una misma pregunta sobre dos conceptos clave, ¿Qué es mejor usar para mis IDs numéricos incrementales, un campo IDENTITY o secuencias?. Ambos son conceptos fundamentales para la generación de valores únicos y juegan un papel crucial en la gestión de datos. En este artículo, vamos a sumergirnos en estos dos conceptos, explorando sus ventajas, desventajas y cuándo es mejor usar uno u otro. Seguro que no acabamos con esta pregunta repetitiva pero, al menos, vamos a intentar reunir todas las herramientas que necesitamos para darle la mejor respuesta. 

IDENTITY en SQL Server

IDENTITY es una propiedad que se puede establecer en una columna de una tabla en SQL Server. Esta propiedad genera automáticamente valores numéricos secuenciales cada vez que se inserta una nueva fila en la tabla. Es muy útil cuando se necesita un identificador único, como una clave primaria. Aunque es muy común su uso para claves primarias, Identity por sí mismo no garantiza la unicidad. Cuando declaramos esta propiedad debemos acompañarla de dos números, el primero llamado seed indica el primer valor que va a tener nuestro campo IDENTITY y el segundo, increment, define el incremento. Es muy común el uso de IDENTITY (1,1) que especifica que empezando desde el número 1 el contador se incrementará en 1. 

Ventajas de IDENTITY

IDENTITY es fácil de implementar y no requiere ninguna gestión adicional. Además, es altamente eficiente en términos de rendimiento, ya que los valores se generan durante la inserción de datos.

Desventajas de IDENTITY

Con Identity, no se puede controlar la secuencia de los números generados. La secuencia siempre comienza en 1 (o cualquier valor inicial especificado) y se incrementa en 1 (o cualquier incremento especificado). No podremos modificar el contador si por ejemplo hemos borrado datos. Así mismo, los valores de Identity están vinculados a una tabla específica. No se pueden compartir entre tablas.

Tampoco es posible garantizar al 100% que los números vayan a ser consecutivos. Si estamos trabajando en un nivel de aislamiento distinto a SERIALIZABLE es posible que en ocasiones encontremos saltos. Otro error común en la numeración se da cuando nos encontramos saltos de 1000 números de golpe, esto se da cuando tenemos paradas inesperadas del servicio de SQL Server. Si durante la parada había una operación a medias SQL incrementará en 1000 el contador de IDENTITY para evitar duplicidades.

Columnas limitadas: Otra de las desventajas es que solo podremos definir la propiedad IDENTITY para una columna en cada tabla.

Inserciones manuales en campos IDENTITY

Cuando queremos insertar manualmente un dato nuevo en un campo IDENTITY deberemos primero habilitar la inserción de identidad. Esto nos permitirá insertar un valor en esa columna. Si el valor insertado es mayor al último que tenga almacenado se establecerá este nuevo como valor de identidad actual.

La sintaxis para habilitar la inserción e identidad es:

SET IDENTITY_INSERT [ [ database_name . ] schema_name . ] table_name { ON | OFF }  

Debemos tener en cuenta que esta opción se establece en tiempo de ejecución y no de análisis y que solo lo podemos tener activado para una tabla por sesión. Si se intenta establecer la opción sobre una tabla teniéndola activada sobre otra se desactivará la anterior para activar la actual

Secuencias en SQL Server

Las Secuencias en SQL Server son objetos de base de datos que generan una secuencia de números únicos. A diferencia de Identity, las secuencias no están atadas a una tabla específica y pueden ser utilizadas por múltiples tablas.

Ventajas de las Secuencias

Las secuencias ofrecen una mayor flexibilidad en términos de gestión de la secuencia de números. Se puede establecer el valor inicial, el incremento, el valor mínimo y máximo, y si la secuencia debe reiniciarse después de alcanzar el valor máximo. Además, las secuencias pueden ser utilizadas por varias tablas, lo que permite mantener una secuencia única a través de múltiples tablas y no tenemos la limitación de solo una por cada tabla. Por último, en cualquier momento podremos manualmente ajustar el contador de nuestras secuencias.

Desventajas de las Secuencias

Las secuencias pueden ser un poco más complejas de implementar y gestionar en comparación con IDENTITY. Aunque las secuencias son generalmente eficientes, pueden tener un impacto en el rendimiento si se utilizan en tablas con un volumen de datos muy alto.

Inserción del valor de la secuencia

Al contrario que con IDENTITY la secuencia no se inserta directamente a la hora de hacer una inserción en la tabla, aunque si podremos lograr este comportamiento definiendo el siguiente valor de la secuencia como valor por defecto de una columna. De esta manera siempre que no se declare manualmente ningún otro valor para la columna se insertará el valor de la secuencia. Esto nos permite inserciones manuales mucho más sencillas para los usuarios finales de la base de datos pero también conlleva un riesgo al no ir el valor de la secuencia ligado al contenido de la tabla.

¿Cuándo usar Identity y cuándo usar Secuencias?

La elección entre Identity y Secuencias depende en gran medida de las necesidades específicas del proyecto. Si se necesita una solución simple y eficiente para generar claves primarias en una sola tabla, IDENTITY puede ser la opción ideal. Sin embargo, si se necesita una mayor flexibilidad y la capacidad de compartir la secuencia de números entre varias tablas, las secuencias pueden ser la mejor opción.

Conclusión

Tanto la propiedad IDENTITY como las secuencias son herramientas poderosas en SQL Server para la generación de valores únicos. Cada una tiene sus propias ventajas y desventajas, y la elección entre una y otra depende de las necesidades específicas del proyecto. Al entender estas herramientas y cómo funcionan, podemos hacer un uso más efectivo de ellas y diseñar bases de datos más eficientes y flexibles. 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, 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

Impacto en el rendimiento de índices FullText

Llevamos los dos últimos artículos hablando de los índices de texto completo (FullText) en SQL Server. Hemos aprendido lo qué son y cómo se administran, sin embargo hay un tema, quizá lo más importante, que habíamos dejado para el final. Y no es otro que su uso y el impacto en el rendimiento. ¿Realmente merece la pena este tipo de índices? Vamos a descubrirlo juntos.

Cláusulas específicas para buscar en índices FullText

Normalmente cuando tenemos que buscar texto dentro de una columna en SQL usamos la cláusula LIKE y nos apoyamos en el carácter % que hace de comodín. Sin embargo, cuando hemos añadido una columna a un índice FullText se nos habilitan otras opciones de búsqueda como son CONTAINS, FREETEXT, CONTAINSTABLE y FREETEXTTABLE. Aunque todas son cláusulas para filtrar por texto tienen algunas diferencias que debemos conocer.

CONTAINS: La Precisión

CONTAINS es una cláusula que permite realizar búsquedas de texto completo en columnas de tipo char, varchar o text dentro de SQL Server. Esta cláusula es especialmente poderosa por su capacidad de buscar palabras o frases específicas, e incluso formas de una palabra, dentro de un texto. Por ejemplo, si queremos encontrar todos los registros que contengan la palabra «optimización», CONTAINS nos facilitará esta tarea con gran precisión.

FREETEXT: La Relevancia 

Por otro lado, FREETEXT es menos estricta que CONTAINS y se utiliza para buscar términos que sean «similares» o relacionados con el texto de la consulta, sin necesidad de que sean exactos. Es decir, FREETEXT no solo nos va a devolver los campos que contengan esa palabra sino también los que contengan algún sinonimo.  Esto es ideal para cuando la intención es más importante que la coincidencia literal, permitiendo una búsqueda más «libre» y basada en la relevancia.

CONTAINSTABLE: Resultados Ordenados

CONTAINSTABLE es una función que extiende las capacidades de CONTAINS, devolviendo una tabla de resultados con las filas que coinciden con la búsqueda, junto con un rango de relevancia, conocido como «rank». Esto permite no solo encontrar las coincidencias, sino también ordenarlas por su relevancia, facilitando la identificación de los resultados más pertinentes.

FREETEXTTABLE: Mayor Flexibilidad en la Búsqueda

Similar a CONTAINSTABLE, FREETEXTTABLE aplica los principios de FREETEXT a una tabla de resultados clasificables. Esta función es crucial cuando buscamos entender el contexto general de los términos de una búsqueda dentro de un conjunto de datos, proporcionándonos una clasificación que nos ayuda a discernir la importancia relativa de cada registro encontrado.

Sintaxis y ejemplos de la búsqueda de texto

Ahora que ya sabemos las diferencias entre las distintas búsquedas vamos a ver como se usan en un caso práctico. Para esto vamos a usar la base de datos de ejemplo de Microsoft AdventureWorks. Como ya sabréis (o no, no importa) esta base de datos tiene datos de ejemplo de una tienda de bicicletas. Vamos a buscar, entonces, por la palabra rendimiento en la tabla de descripciones de los productos. Lamentablemente no tenemos una base de datos AdventureWorks con datos en español así que tendremos que buscar en inglés pero es solo por esto. Vosotros tendreis que buscar en el idioma que tengáis vuestros datos y, muy importante, tendréis que haber creado directamente el índice en ese idioma (si no sabéis como se hace os lo conté aquí). 

Vamos a hacer la misma búsqueda con todas las posibles opciones que hemos visto antes:

Podríamos entrar aquí y ahora en todas las opciones avanzadas de filtrado que incluyen cada una de estas opciones frente al tradicional y simple LIKE pero, convertiría este artículo en eterno y tampoco es el objetivo del post. Si queréis profundizar más tenéis la documentación oficial y si queréis que veamos aquí algunos ejemplos podeis pedirmelo y lo haremos. 

Rendimiento en las búsquedas de texto

Vamos ahora a comparar el rendimiento de las consultas anteriores. Para que el ejemplo tenga más relevancia he creado aproximadamente unos 200.000 registros en la tabla en lugar de los menos de 800 que trae cuando restauramos la base de datos. No sufráis por eso que después de eso también he actualizado los índices y estadísticas de la tabla. Esto nos va a permitir verificar mejor las diferencias.

Estos han sido los resultados ejecutando las anteriores consultas:

CláusulaTiempo de CPULecturas lógicasPorcentaje del plan
LIKE781 milisegundos4365 páginas77%
CONTAINS< 1 milisegundo278 páginas5%
FREETEXT< 1 milisegundo278 páginas7%
CONTAINSTABLE< 1 milisegundo278 páginas5%
FREETEXTTABLE< 1 milisegundo278 páginas7%
FullText_Performance1
FullText_Performance2

Las conclusiones son obvias, el mayor consumo de recursos es con Like, cuando no se usa el índice FullText tardando 780 veces más en completar la consulta y leyendo 34 Mb de información (4365 páginas * 8Kb por página / 1024 = 34 Mb) frente a los solo 2 Mb de información que se leen las consultas que sí hacen uso del índice de texto completo. 

Rendimiento en escrituras

Ya hemos hablado en varias ocasiones de esto pero no está de más recordarlo, los índices en SQL “no son gratis” y por no son gratis me refiero a que hay un precio a pagar por toda esta mejora de rendimiento en las lecturas. En concreto el precio a pagar es un gran empeoramiento de las escrituras. Para verificar hasta dónde es negativo este impacto en las escrituras he creado una tabla en mi SQL Server con la misma estructura que con la que estamos haciendo la prueba y con los mismos datos pero sin el índice de texto completo. Si que tiene el resto de los índices que tiene la tabla original (PK + Nonclustered). A continuación he insertado en las dos tablas los mismos 100.000 registros para medir los tiempos. 

FullText_Performance3

Como podéis ver en la imagen, el resultado de la inserción en la tabla sín índice FullText ha tardado 225 milisegundos frente a 1079 milisegundos en la tabla que tiene índice de texto completo. En cuanto a la información que se ha necesitado leer para hacer la inserción encontramos que para insertar en la tabla con FullText hemos tenido que leer 12,6 Gb de información mientras que para la que no tiene ese índice solo hemos tenido que leer 259,2 Mb.

Conclusión

Los índices de texto completo o FullText pueden ser un gran aliado en las consultas de lecturas, no tanto en las escrituras, donde nos pueden llegar a dar verdaderos problemas de rendimiento. Además, al contrario que en los índices normales donde su creación es transparente, para aprovechar la mejora de un índice FullText tendremos que adaptar nuestro código y usar las cláusulas específicas que usarán el índice. 

Espero que esta serie de artículos te haya ayudado a comprender mejor los índices de texto completo y a poder analizar si son o no beneficiosos para tus escenarios de uso actuales y futuros. 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 Índices, Rendimiento, SQL Server, 0 comentarios

Creando y manteniendo índices FullText

Continuamos con el tema de ayer sobre los índices de texto completo y hoy vamos a centrarnos en aspectos más prácticos. Si aún no has leído el artículo introductorio de ayer sobre los índices FullText te recomiendo que lo hagas antes de seguir con este para saber de lo que estamos hablando. Si ya leíste vamos a hacer un pequeño resumen para reforzar los conceptos clave. Los índices de texto completo o FullText son unos índices especiales que nos ayudarán en nuestras búsquedas sobre columnas con gran cantidad de texto. Además, tienen la particularidad de que se organizan en catálogos, aspecto clave para su creación y futuro mantenimiento.

Requisitos para crear un índice FullText

Para crear los índices FullText lo primero que necesitaremos será tener instalada la característica de SQL con la que trabajan, no tiene pérdida se llama FullText o Texto Completo dependiendo del idioma de nuestro instalador. Una vez instalada tenemos que asegurarnos de tener corriendo el servicio para la extracción de texto completo, tampoco tiene pérdida y lo localizaremos por su nombre rápidamente junto con el resto de servicios en el administrador de configuración de SQL Server. 

Una vez estemos seguros de que el servicio está instalado y en ejecución podremos proceder con la creación del catálogo que, recordad que es requisito imprescindible para este tipo de índices. Para crear el catálogo usaremos la sintaxis siguiente sintaxis: 

Para ver los catálogos existentes podemos hacerlo en SSMS, desplegando la carpeta almacenamiento dentro de la base de datos o con la siguiente consulta:

FullText_Catalog

Creación de índices FullText

Una vez que cumplamos con los requisitos anteriores estaremos ya preparados para crear nuestro índice FullText. Tenemos que saber que podemos crear índices de texto completo tanto en tablas como en vistas indexadas pero solo uno por tabla (o vista). El índice de cada tabla podrá contener hasta 1024 columnas. La sintaxis de creación es la siguiente:

No voy a entrar en todas las opciones de creación de un índice FullText, para eso podéis consultar la documentación oficial aquí. Nos vamos a centrar en las más importantes. Como veis es parecido a la sintaxis de creación de índices que todos conocemos. Especificaremos la tabla sobre la que crearlo y las columnas que incluirá. Como opción podemos definir el idioma del texto de esas columnas para las búsquedas, si no lo especificamos se usará el idioma por defecto de la instancia. Esto es importante si tenéis el servidor en inglés pero los datos en español, por ejemplo. Esta opción de language admite tanto el alias como el lcid de los idiomas de la vista del sistema sys.syslanguages.

Otro de los aspectos clave y que es obligatorio es definir un índice de referencia con la clave para nuestro nuevo índice FullText. Debe ser una clave única que no admita valores nulos. Para un mejor rendimiento se recomienda que sea un identificador único numérico. También debemos definir el catálogo sobre el que se creará el índice. Si no definimos el catálogo se usará el por defecto y si no hay uno por defecto veremos un bonito error, así que, aseguraos de definirlo bien.

Para terminar con esta sección de creación e índices FullText es importante destacar la opción de Change_Tracking que definirá la propagación de nuestro índice. Esto significa que define el comportamiento cuando hay una modificación de la tabla (Insert, Update o Delete). Por defecto está en modo AUTO y los cambios se propagan de la tabla al índice FullText en tiempo real pero podemos definirlo en modo manual y que solo se propaguen con una sentencia SQL que ejecutaremos a voluntad o programaremos en un job. La sentencia para propagar los cambios de la tabla al índice es:

Palabras irrelevantes

Como podéis imaginar, indexar todo un texto puede suponer unos requisitos de espacio tremendos, para evitar esto en la medida de lo posible SQL Server implementa lo que se llaman las palabras irrelevantes y las listas de palabras irrelevantes (stopword y stoplist). Si os habéis fijado antes, a la hora de crear un índice FullText podíamos definir una de estas stoplist.

Palabras irrelevantes

Una palabra irrelevante puede ser por ejemplo un código que guardamos pero que no se usa o palabras que sí tienen significado lingüístico pero que no son relevantes para las búsquedas como podrían ser preposiciones y otras. Por ejemplo en español no puede que no queramos indexar las palabras “un”, “y”, “el”, «de «, «hasta «, etc.

Listas de palabras irrelevantes

Para poder gestionar las palabras irrelevantes SQL Server usa unos objetos que se llaman lista de palabras irrelevantes o stoplists. Podemos encontrarlos desplegando la carpeta almacenamiento dentro de la base de datos (mirad en la imagen de antes). Para crear nuestras propias stoplists podemos hacerlo desde este apartado de SSMS o con la sintaxis CREATE FULLTEXT STOPLIST.

Mantenimiento de índices FullText 

Como ya adelantamos en el artículo de ayer, el mantenimiento de los índices FullText se realiza sobre los catálogos. Para ello podemos hacerlo desde el SSMS haciendo click derecho sobre el catálogo y dando a Rebuild o por T-SQL. Si lo hacemos por T-SQL tendremos la posibilidad de reorganizar los índices sin necesidad de reconstruirlos. Si optamos por un REBUILD se borrarán todos los índices del catálogo y se volverán a crear eliminando así la fragmentación. Puede ser que solo queramos hacer el mantenimiento a un índice, en este caso podemos borrarlo y crearlo de nuevo manualmente. La sintaxis para hacer el mantenimiento de un catálogo es:

Si os fijáis, con esta instrucción podríamos también definir este catálogo como el por defecto.

Conclusión

Hoy hemos aprendido cómo podremos lidiar con los FullText índices como DBAs, esto sumado a lo que vimos ayer y a lo que veremos en el próximo artículo sobre su uso es todo lo que necesitamos para controlar este tema. Si queréis profundizar más en detalle os recomiendo bucear por la documentación oficial que os he compartido y por todas las demás páginas de Microsoft sobre los índices de texto completo. A mi me parece un mundo apasionante y del que poca gente conoce todos los detalles. ¿Quién sabe? Igual algún día tener estos conocimientos puede marcar la diferencia para el trabajo de vuestros sueños.

Espero que este artículo te haya proporcionado una visión profunda de los índices FullText o de texto completo en SQL Server. 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 Índices, Rendimiento, SQL Server, 0 comentarios

Índices de texto completo (Full-Text Indexes)

Volvemos a la carga con un artículo sobre índices, uno de los temas más importantes para el rendimiento de nuestras bases de datos y por ello sobre lo que más contenido tenemos en el blog. Si no has visto los artículos anteriores los tienes todos aquí. A estas alturas no es una sorpresa para nadie que diga que los índices son nuestros mejores aliados para optimizar las consultas y mejorar el rendimiento. Hoy, vamos a sumergirnos en el fascinante mundo de los índices de texto completo o Full-Text index en SQL Server. Este tipo de índice especial y no tan conocido en SQL Server nos va a permitir buscar en grandes cadenas de texto que, sin estos índices siempre es peor que un dolor de muelas.

¿Qué son los Índices de Texto Completo?

Los índices de texto completo son un tipo especial de índice de SQL Server que nos proporciona una solución eficaz para buscar palabras y frases dentro de una gran cantidad de datos de texto en SQL Server. A diferencia de los índices tradicionales, que se basan en la comparación de valores, los índices de texto completo nos permiten realizar búsquedas complejas en textos largos y no estructurados.

Creación de Índices de Texto Completo

Crear un índice de texto completo en SQL Server es un proceso sencillo. Primero, necesitamos una columna con un tipo de datos de texto. Luego, antes de poder crear en índice necesitaremos un catálogo de texto completo. Una vez creado el catálogo podremos crear nuestros índices de texto completo en sí. 

La creación de catálogos es un aspecto fundamental para los índices de texto completo y de cómo los estructuremos ya que nos va a permitir organizarlos y va a afectar al rendimiento futuro de nuestras tareas de mantenimiento.

Uso de Índices de Texto Completo

Una vez creado el índice de texto completo, podemos utilizar la cláusula CONTAINS en nuestras consultas para buscar palabras o frases específicas. También podemos usar la cláusula FREETEXT para realizar búsquedas más generales.

Desventajas de los Índices de Texto Completo

Los índices de texto completo en SQL Server son una herramienta poderosa, pero como cualquier tecnología, tienen sus limitaciones y desventajas. Aquí vamos a nombrar algunas de las más importantes:

Espacio Adicional

Los índices de texto completo ocupan espacio adicional en el disco. Esto puede ser significativo en bases de datos con muchas tablas grandes y varios índices creados. Por lo tanto, es importante considerar el equilibrio entre el rendimiento de la consulta y el uso del espacio en disco.

Rellenado de Índices

El proceso para crear y mantener un índice de texto completo se denomina rellenado (o rastreo). Hay tres tipos de rellenado de índice de texto completo: rellenado completo, rellenado basado en el seguimiento de cambios, y rellenado incremental basado en una marca de tiempo. Este proceso puede ser costoso en términos de recursos y tiempo, especialmente para bases de datos grandes.

Mantenimiento de Índices de Texto Completo

Como cualquier otro índice, los índices de texto completo requieren un mantenimiento regular para garantizar su eficiencia. SQL Server proporciona varias herramientas y técnicas para ayudarnos en esta tarea. Al igual que en el resto de tipos de índices estas son REORGANIZE y REBUILD. Sin embargo, en el caso particular de estos índices las tareas de mantenimiento se realizan sobre el catálogo afectando a todos los índices incluidos y no se puede hacer sobre un único índice a petición. Siempre nos queda la opción de eliminar el índice y volverlo a crear pero no parece una opción aceptable. Por si esto fuera poco es un proceso que no está incluido en las principales soluciones de mantenimiento como OLA Hallengren.

Recomendaciones de rendimiento

Como acabamos de mencionar, optimizar el rendimiento de los índices de texto completo en SQL Server puede ser un desafío. Vamos a ver las mejores recomendaciones que pueden ayudarnos:

Arquitectura y Mantenimiento

Es una buena idea limitar la selección de columnas de clave de texto completo a una columna pequeña. Aunque se admite una columna de 900 bytes, se recomienda usar una columna de clave menor en un índice de texto completo, int y bigint ofrecen el mejor rendimiento.

Podremos reorganizar el catálogo de texto completo utilizando ALTER FULLTEXT CATALOG REORGANIZE. Esto debe hacerse antes de realizar pruebas de rendimiento, ya que la ejecución de esta instrucción produce una mezcla maestra de los índices de texto completo del catálogo.

Uso y consultas

Siempre es mejor combinar varios predicados CONTAINS en un predicado CONTAINS. En SQL Server puedes especificar una lista de columnas en la consulta CONTAINS.

Si solo necesitas información de clave de texto completo o de clasificación, usa CONTAINSTABLE o FREETEXTTABLE en lugar de CONTAINS o FREETEXT, respectivamente.

Para limitar los resultados y aumentar el rendimiento, usaremos el parámetro top_n_by_rank de las funciones CONTAINSTABLE y FREETEXTTABLE top_n_by_rank permite volver a recuperar solo las coincidencias más pertinentes.

Comprobar el Plan de Consultas

Y como siempre, deberemos comprobar constantemente el plan de consultas de texto completo para asegurarnos de que se selecciona el plan de combinaciones adecuado. Usaremos una sugerencia de consulta o forzaremos un plan de ejecución en Query Store si es necesario.

Conclusión

Los índices de texto completo son una herramienta potentísima en SQL Server que nos permite realizar búsquedas eficientes en grandes volúmenes de datos de texto. Aunque su creación y mantenimiento pueden requerir un poco de esfuerzo adicional, los beneficios que aportan en términos de rendimiento y flexibilidad de las consultas valen la pena.

Esperamos que este artículo te haya proporcionado una visión profunda de los índices de texto completo en SQL Server. Como siempre, te animamos 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 Índices, Rendimiento, SQL Server, 3 comentarios

Dimensionamiento correcto de un servidor

En nuestro trabajo como administradores de bases de datos, una de las tareas más cruciales y desafiantes a las que nos vamos a enfrentar es calcular el dimensionamiento de un servidor SQL Server. Este proceso implica determinar la cantidad de recursos necesarios para que el servidor funcione de manera óptima, teniendo en cuenta factores como el número de usuarios, la cantidad de datos y las operaciones de la base de datos.

Consideraciones Iniciales

El dimensionamiento adecuado de un servidor SQL Server no es una tarea sencilla. Requiere un conocimiento profundo de las características y capacidades del servidor, así como de las necesidades y demandas de la base de datos y las aplicaciones que se ejecutan en él. Antes de sumergirnos en cálculos y métricas, es esencial entender la carga de trabajo que manejará nuestro nuevo servidor. Esto implica analizar el volumen de transacciones, la concurrencia de usuarios, y los patrones de acceso a los datos. Solo con un conocimiento profundo de estas variables podemos comenzar a esbozar los requisitos de nuestro servidor. 

Si el nuevo servidor se va a usar para sustituir uno ya existente lo vamos a tener mucho más fácil, podremos basarnos en el estado actual y analizar sus puntos flacos para tratar de mejorarlos. Hablamos de migraciones en este otro artículo.

El verdadero reto lo tendremos cuando nos enfrentemos a un escenario nuevo, desde 0. En este caso, será crucial la colaboración de los equipos responsables de los datos o de las aplicaciones, en especial de un buen project manager, además de otros departamentos de negocio que nos puedan indicar previamente las expectativas de carga de trabajo y necesidades de almacenamiento.  En un mundo ideal, todas estas necesidades estarían especificadas en la documentación del proyecto y no tendríamos que hacer más preguntas. Pero, como eso no es lo que nos solemos encontrar (y menos mal, porque así tengo algo de lo que escribiros), vamos a analizar en profundidad que debemos tener en cuenta.

Aspectos a evitar

A lo largo de mis años de experiencia me he enfrentado a las suficientes migraciones y nuevos despliegues como para haber elaborado una lista con los aspectos que si o si debo evitar si quiero llevar el proyecto a buen puerto. Os comparto un pequeño resumen:

  • Subestimar el crecimiento: Y no solo me refiero a los datos, eso es quizá lo de menos. Debemos tener una idea clara de las necesidades de recursos del servidor para que un futuro aumento de la carga de trabajo no nos degrade el rendimiento o, directamente, tumbe el servicio.
  • Falta de monitorización: Es imprescindible monitorizar completamente el servidor tanto antes de la migración si es el caso, como tras la implementación, SIEMPRE. Si disponemos de un servidor antiguo que tenemos que migrar, no monitorizarlo y conocer su comportamiento completamente nos llevará a problemas en un futuro. No hagamos conjeturas, y apoyémonos en datos. 
  • No conocer los objetivos comerciales: Este punto está muy ligado al primero pero tiene su razón de ser como punto independiente. Puede que el equipo de desarrollo haya desplegado una aplicación para los 500 clientes actuales y esos sean los datos que tenemos nosotros pero, si desde la dirección se han marcado el objetivo de doblar esa cifra cada ejercicio, pronto nuestro servidor no dará más de sí.
  • Sobreaprovisionamiento: Puede parecer una buena opción visto lo visto pero nada más lejos de la realidad. Aprovisionar más recursos de los que necesitamos o vamos a necesitar a corto plazo será un malgasto de recursos y no nos dejará en buen lugar como profesionales.

Cómo calcular un dimensionamiento correcto

Ahora que ya sabemos los puntos clave que debemos evitar vamos a ver uno a uno como debemos hacerlo.

Carga de trabajo

Como ya hemos dicho, comprender la carga de trabajo que afrontará nuestro servidor es el aspecto fundamental para un correcto dimensionamiento. Si hablamos de un servidor completamente nuevo nos tendremos que basar en las necesidades que nos indiquen los responsables del proyecto y cobrarán más sentido el resto de apartados. Si por el contrario estamos sustituyendo un servidor existente este punto es de vital importancia. Usaremos todos los recursos que tengamos a nuestra disposición y en ocasiones un trabajo de monitorización previo nos facilitará el trabajo.

En este sentido, a mi me gusta tener siempre en mis servidores un proceso que controle el crecimiento de los ficheros de base de datos (usando la vista sys.master_files por ejemplo) y que lo persista en una tabla de configuración. De esta manera a la hora de calcular el dimensionamiento podremos hacernos una idea clara del histórico de crecimiento de nuestras bases de datos. 

Para calcular las necesidades de otros recursos echaremos mano de las DMV que SQL Server pone a nuestra disposición, de Query Store o del monitor de rendimiento de Windows. Prestaremos especial atención a los tiempos de espera de nuestras consultas para, en la medida de lo posible, acabar con esos cuellos de botella.

Estrategia proactiva

Las bases de datos no son objetos estáticos, están continuamente cambiando y como tal, nosotros tendremos que monitorizar y verificar que las previsiones iniciales que hicimos son correctas. No solo hablo de las pruebas antes del “go live” sino de todo el ciclo de vida del servidor. Una buena monitorización nos permitirá pronosticar una futura necesidad de recursos y anticiparnos a ese dimensionamiento antes de que exista degradación en el rendimiento del servidor. 

El mercado está repleto de soluciones integrales de monitorización de rendimiento de SQL Server pero, cuando el presupuesto no lo permite, tendremos que ser creativos con las soluciones nativas sin dejar de lado esta tarea. Nuevamente las DMV de SQL Server, Query Store y el monitor de rendimiento de Windows serán nuestros aliados. Además, si persistimos estos datos, seremos capaces de analizar tendencias y predecir comportamientos en un futuro (de esto sabe mucho la gente de BI).

Objetivos Comerciales y dimensionamiento

No trabajamos solos, en la mayoría de los casos nuestras bases de datos son una pieza clave para el desempeño de la actividad de negocio. Sería de necios pensar que podemos hacer nuestro trabajo sin alinearnos con el resto de departamentos e ignorando los objetivos comerciales de nuestra organización. En este sentido, cuanto mayor sea nuestro conocimiento del sector, de la empresa en particular y de sus objetivos mejores previsiones podremos hacer.

Igualmente, esto va en los dos sentidos, es nuestra responsabilidad hacernos valer y que los jefes que toman las decisiones sepan que tienen que contar con nosotros. He trabajado en sitios donde no era así, se tomaban decisiones de negocio sin comunicar los objetivos comerciales al departamento de IT y sin trasladar las necesidades de crecimiento. ¿De verdad piensas que tus sistemas están preparados para asumir de la noche a la mañana una fusión que duplique la cantidad de clientes? 

Podríamos resumir este apartado en tres aspectos fundamentales, conoce los objetivos comerciales, involucra a todas las partes interesadas en la planificación y pronostica de manera adecuada la capacidad de los sistemas antes de que sea tarde. 

Escalabilidad, prepárate para un ajuste en el dimensionamiento

Como último punto a tener en cuenta pero no por ello menos importante tenemos que ser capaces de diseñar un sistema capaz de crecer. Ya hemos dicho que nuestras bases están vivas y cambian con el tiempo, normalmente, si todo va bien, crecerán. También hemos visto que sobredimensionar de primeras un sistema puede ser un malgasto de recursos. Aquí es donde entra en juego la escalabilidad. No voy a profundizar más en el concepto porque ya le hemos dedicado un artículo completo al tema que puedes leer aquí.

Es importante que conozcas y que trabajes conjuntamente con el equipo de infraestructura para brindar a tus servidores de esta capacidad. Y no solo con sistemas, confirma con los equipos de desarrollo si sus aplicativos están preparados para un escalado horizontal. Si es así, considera planificar nuevas máquinas, licencias y todo lo necesario para asumir el crecimiento futuro, aunque solo sea una planificación y no se implante a corto plazo es importante tenerlo documentado. 

Sin embargo, este escenario no es lo más común. Normalmente priorizaremos un escalado vertical, aumentando los recursos de nuestro servidor siempre que sea posible. Aquí entra en juego ese trabajo conjunto con los compañeros de sistemas del que estábamos hablando antes. No es lo mismo un escalado vertical en una máquina física que en una virtual o en la nube. Asegúrate de que tienes el presupuesto y la capacidad para crecer y hacer frente a las futuras capacidades del servicio.

Conclusión

El dimensionamiento adecuado de un servidor SQL Server es esencial para garantizar su rendimiento y eficiencia. Al tener en cuenta factores como la carga de trabajo, el rendimiento, la capacidad de almacenamiento y la concurrencia, y al utilizar las herramientas y técnicas adecuadas, podemos hacer una estimación precisa de los recursos necesarios para nuestro servidor. Aun así, el trabajo no termina ahí, las bases de datos están en constante crecimiento y tenemos que ser capaces de adelantarnos a las necesidades de recurso y redimensionar el servidor correctamente. 

Espero que este artículo te haya sido útil y que te ayude a dimensionar correctamente tus 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 Otros, 1 comentario