SQL Server

Aquí encontraras todos nuestros post relacionados con SQL Server desde cero hasta un nivel avanzado. Desde infraestructura hasta modelado de datos.

Cumplir con la ISO 27001 en SQL Server

Adaptar una instancia de SQL Server para cumplir con ISO 27001 no es simplemente activar Transparent Data Encryption y dormir tranquilo. Si alguien te lo ha vendido así, que no te extrañe si el día de la auditoría tienes que improvisar explicaciones más rápido que un becario ante un DROP DATABASE en producción. En este artículo vamos a abordar cómo orientar la configuración y operación de SQL Server para alinearse de verdad con los requisitos de esta norma. Sin humo. Sin soluciones mágicas. Con criterio técnico.

Seguridad en serio: ISO 27001 aplicada a SQL Server

La ISO/IEC 27001 no es una checklist de parches ni una receta genérica para “estar seguros”. Es una norma internacional que define cómo establecer, implementar y mantener un Sistema de Gestión de Seguridad de la Información (SGSI). Y sí, eso implica tanto políticas como controles técnicos. Justo ahí es donde entra SQL Server: no vamos a “certificar” el motor como tal, sino a demostrar que su configuración forma parte de un sistema de seguridad coherente, mantenido y documentado.

Esto significa que no basta con que algo sea seguro. Tiene que serlo, parecerlo, estar documentado y poder demostrarse con evidencias. ¿Te suena familiar? Como cuando configuras xp_cmdshell bien restringido y luego alguien te pregunta por qué no está deshabilitado del todo.

Control de accesos: la piedra angular de la 27001

Si hay una sección que una auditoría va a mirar con lupa, es esta. Y con razón. La gestión de identidades y accesos (IAM) es una de las piedras angulares del SGSI. Aquí es donde SQL Server suele enseñar sus vergüenzas.

Hay que empezar por lo básico: el control estricto de quién accede, a qué y cómo. Eso implica eliminar cuentas de servicio genéricas y acabar con el uso de sa (y si alguien lo necesita “por si acaso”, que se compre una linterna y se prepare para picar en la mina). La autenticación integrada con Active Directory debe ser la norma, no la excepción, y si aún usamos SQL Login para aplicaciones, que al menos estén cifrados y restringidos por roles mínimos.

Es fundamental auditar permisos y revisar regularmente los roles. Y no, eso no se hace con un Excel que alguien actualizó “hace unos meses”. Hay que generar informes automáticos, versionados, y con trazabilidad. Si alguien se añade al rol db_owner y nadie se entera, no tenemos un SGSI, tenemos una partida de ruleta rusa.

Registro y trazabilidad: En la 27001 lo que no se audita no existe

ISO 27001 es bastante explícita en esto: todo acceso relevante y toda operación sensible debe poder ser rastreada. Aquí entra en juego SQL Server Audit, nuestro viejo amigo. Bien configurado, nos permite registrar accesos, cambios de permisos, ejecuciones de procedimientos críticos y cualquier otra acción que entre en la categoría de “esto podría ser un problema si lo hace el usuario equivocado”.

Importante: no vale con activar la auditoría. Hay que almacenarla de forma segura, revisar los logs con periodicidad definida y tener mecanismos de alerta ante anomalías. Un fichero .sqlaudit guardado en una carpeta que nadie mira es como un extintor de cartón en una vitrina de cristal: muy decorativo pero no vale de nada.

Si usas Extended Events para auditorías avanzadas, perfecto. Pero asegúrate de que no sea algo que sólo entiendes tu y otro DBA senior. La documentación debe existir y ser entendible por otros perfiles técnicos.

Cifrado y protección de datos: porque el disco no se protege solo

El cifrado es una parte clave del cumplimiento, pero también uno de los terrenos donde más se abusa del postureo técnico. Que sí, que activar TDE está bien, pero eso no convierte el sistema en “cumplidor”. Hay que ir más allá.

Hablamos de cifrar tanto en reposo como en tránsito. Para lo primero, TDE más Backup Encryption son un buen punto de partida. Pero si hay datos sensibles, necesitamos también Always Encrypted para proteger valores a nivel de columna. Y eso implica repensar aplicaciones y procedimientos. ¿Molesta? Sí. ¿Es necesario? También.

El tráfico por la red entre cliente y servidor debe ir cifrado con TLS. Nada de conexiones en texto plano, y mucho menos con certificados auto-firmados abandonados en un rincón desde 2012. Una revisión de certificados y políticas de cifrado debe formar parte de las tareas periódicas del equipo de DBA, no un apéndice olvidado.

Lo que dice la ISO 27001 de gestión de vulnerabilidades y actualizaciones

Poner los parches de seguridad no es opcional, por mucho que el jefe de proyecto diga que “no conviene tocar nada en producción” o esa frase que tanto hemos oído “si funciona no lo toques”. ISO 27001 exige un proceso definido de gestión de vulnerabilidades, y eso implica inventario, evaluación del impacto, planificación de despliegues y pruebas.

Aquí SQL Server se alinea bien si lo integramos en un ciclo de gestión de parches serio. No vale con instalar el último CU cada seis meses “cuando haya tiempo”. Debemos definir criterios de urgencia, ventanas de mantenimiento, y mecanismos de rollback (sí, backups y pruebas en entornos espejo).

Si alguien aún depende del mail de Microsoft para enterarse de un nuevo CVE, hay que revisar el proceso. Un SGSI que no tiene un canal automático de recepción y evaluación de alertas es como un antivirus sin actualizaciones.

Disponibilidad y recuperación: lo que nadie quiere probar

La norma también cubre la resiliencia del servicio y la capacidad de recuperación ante desastres. Aquí es donde SQL Server tiene mucho que ofrecer, pero sólo si lo usamos bien.

Necesitamos backups automáticos, verificados y documentados. ¿Y las restauraciones? También. No basta con tener copias: hay que probar que funcionan y registrar esas pruebas. Los planes de recuperación deben contemplar diferentes escenarios: pérdida parcial, fallo total, ransomware…

Además, si hay servicios críticos, hay que implementar HA: desde grupos de disponibilidad Always On, hasta clústeres de failover, pasando por réplicas geográficas si el contexto lo exige. Pero cuidado: ningún mecanismo de alta disponibilidad sustituye una buena política de respaldo. El que lo crea debería dejar de leer folletos de marketing.

Documentación y procedimientos: el arte de escribir sin florituras para la 27001

Todo lo anterior no sirve de nada si no está documentado. Y con documentado no nos referimos a un PDF lleno de obviedades técnicas que nadie ha revisado desde 2021.

Debemos tener procedimientos claros para el alta y baja de usuarios, cambios de permisos, mantenimiento programado, revisión de auditorías, gestión de incidencias, y un largo etcétera. Todo ello debe estar accesible, versionado y validado. No se trata de cumplir por cumplir, sino de poder demostrar que sabemos lo que hacemos, cómo y por qué.

Además, durante una auditoría, estos documentos son el salvavidas que puede evitar un informe lleno de “no conformidades”. Si todo el conocimiento está en la cabeza del DBA veterano que ahora trabaja en otra empresa, tenemos un problema. Y un problema de los gordos.

Cultura de seguridad: porque no todo es técnica en la ISO 27001

Aunque suene raro en un blog de DBAs, ISO 27001 también exige que la organización tenga una cultura de seguridad. Esto implica formación, concienciación y procesos que no dependan exclusivamente de las ganas del equipo técnico.

Desde el punto de vista de SQL Server, esto se traduce en revisar que los desarrolladores no guarden contraseñas en texto plano, que las aplicaciones no se conecten como sa, y que los cambios estructurales no se hagan directamente en producción “porque lo pide el jefe”. En resumen: sentido común, respaldado por normas internas.

Conclusión

Adaptar SQL Server para cumplir con ISO 27001 no es cuestión de marcar casillas, sino de asumir responsabilidades. Hay que proteger los datos, controlar accesos, auditar acciones, cifrar donde toca, aplicar parches sin miedo y documentar sin aburrir.

No se trata de ser paranoico, sino profesional. De tener un entorno donde, si mañana alguien pide un informe de seguridad, podamos sacarlo sin sudar. Y si hay una brecha, podamos demostrar que lo hicimos todo bien. Porque al final, eso es la seguridad real: no solo evitar el desastre, sino estar preparados para responder con firmeza si llega.

Como siempre, que nadie os venda soluciones milagrosas. La seguridad en SQL Server, como todo lo que merece la pena, se trabaja. Y si lo hacemos bien, no solo cumplimos ISO 27001: dormimos un poco más tranquilos.

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, SQL Server, 0 comentarios

Grupos de alta disponibilidad Always On Distribuidos

Hay momentos en la vida de un DBA en los que la alta disponibilidad ya no es suficiente. Hemos sobrevivido a clústeres fallidos, a discos compartidos corruptos y a réplicas que se desconectan con la gracia de una llamada de Teams a las 3 de la madrugada. En ese punto, cuando el entorno ya es exigente, el SLA nos aprieta y la palabra «disponibilidad» se queda corta, es cuando entramos en el terreno de los Availability Groups distribuidos.

Y no, no hablamos de tener un par de réplicas en distintas zonas de disponibilidad dentro del mismo centro de datos. Hablamos de desacoplar entornos completos en distintas regiones, con su propio clúster, su propia lógica de failover, y aún así, mantener la sincronización de nuestras queridas bases de datos. Bienvenidos al club.

¿Qué demonios son los AG distribuidos?

Un AG distribuido (Distributed Availability Group, para los amigos) es una especie de “supergrupo” de alta disponibilidad. No estamos montando un único AG con réplicas dispersas. Estamos conectando dos AG independientes como si fueran nodos de un mismo sistema. Y eso lo cambia todo.

Cada uno de los AG que participan en un DAG (sí, también lo llaman así) tiene su propia topología: su clúster de Windows, sus réplicas, su configuración de quórum, su failover automático. Se comportan como entornos autónomos, que además se sincronizan entre sí a través de una réplica intermedia que hace de “puente” entre ambos mundos. ¿El resultado? Podemos tener un AG en Madrid y otro en Dublín, y replicar entre ellos de forma controlada, tolerando fallos completos del entorno primario sin perder la cabeza.

No es magia. Es ingeniería. Y, como todo lo potente, requiere cabeza y experiencia.

Arquitectura de un DAG: dos mundos bien separados

La gracia del AG distribuido es que cada uno de los AG participantes se gestiona por separado. Esto nos da una ventaja brutal en términos de recuperación ante desastres: si uno se cae por completo, el otro puede activarse sin necesidad de que el primero esté en línea. No hay dependencia directa entre ellos, ni a nivel de clúster, ni de quorum, ni de discos compartidos. Cada AG es soberano en su dominio, y eso, en un mundo donde los CPDs pueden arder, es oro puro.

La configuración básica requiere lo siguiente:

  • Dos AG independientes, cada uno con su propio clúster de Windows.
  • Al menos una réplica en cada AG que actuará como “forwarder” (la que se conecta con el otro AG).
  • Comunicación de red directa entre las réplicas forwarders (y permisos adecuados, claro).
  • Certificados válidos en ambos entornos si usamos endpoints con autenticación por certificado (spoiler: casi siempre).
  • DNS y nombres de servidor que no se pisen entre sí. Si tienes dos réplicas llamadas SQLSRV01 en distintas regiones, vas a llorar.

¿Resultado? Una topología que no depende de un solo clúster de Windows, que permite failover regional controlado, y que puede integrarse perfectamente con estrategias de backup y DR serias.

La sincronización es asíncrona. Y eso está bien

Una pregunta habitual: ¿puedo tener un DAG con sincronización síncrona?

Respuesta corta: no.

Respuesta larga: la sincronización entre los dos AG de un DAG siempre es asíncrona. No es negociable. Y antes de que alguien lo vea como una limitación, recordemos que estamos hablando de replicar entre regiones completas, separadas por cientos o miles de kilómetros. Pedir sincronía aquí es como pedirle baja latencia a una conexión satelital. Lo importante es entender que esto no es para alta disponibilidad de datos en tiempo real, sino para continuidad del negocio ante desastres mayores.

Si necesitamos RPO cero, esto no es para nosotros. Si podemos tolerar unos segundos (o minutos) de pérdida en caso de caída total del entorno primario, entonces un DAG puede ser nuestra mejor baza.

¿Qué se puede hacer con Always On Distribuidos?

Lo primero y más importante: podemos tener una réplica totalmente operativa en otra región, lista para convertirse en nueva primaria si la original cae. Esta réplica puede formar parte de un AG secundario completo, con su propio listener, sus propias réplicas locales, y servir tráfico de lectura si así lo queremos.

Lo segundo: la recuperación ante desastres se convierte en un proceso autónomo. Si se va la luz en todo nuestro entorno primario (sí, ha pasado), podemos activar el AG secundario sin tener que reconstruir el entorno entero o esperar a que vuelva a estar online. Y esto no solo ahorra tiempo: salva el negocio.

Y lo tercero: permite hacer actualizaciones o migraciones sin downtime completo. Podemos preparar todo en el AG secundario, sincronizar, hacer el failover distribuido, y luego ajustar el entorno primario con tranquilidad. Es una forma de reducir riesgos en cambios grandes sin jugar al funambulista con el entorno de producción.

El failover en los AG Distribuidos: aquí mandamos nosotros

Un punto clave en los AG distribuidos es que no hay failover automático entre los dos AG. Esto es deliberado. No estamos hablando de un nodo que se cae por una hora y queremos rebotarlo automáticamente. Estamos hablando de fallos graves, donde lo último que queremos es que el sistema tome decisiones por su cuenta sin entender el contexto.

Por eso, el failover entre AGs distribuidos es manual. Y eso está bien. Podemos automatizarlo con scripts, orquestarlo con herramientas de gestión, y tenerlo documentado al detalle. Pero el botón rojo lo apretamos nosotros, cuando hemos validado que el entorno primario está realmente muerto y no va a levantarse en los próximos 5 minutos.

Una vez hacemos el failover, el AG secundario se convierte en el nuevo primario del DAG. Desde ahí, podemos operar normalmente, restaurar backups, servir peticiones y mantener el negocio en marcha. Cuando el entorno primario vuelva, podremos reintegrarlo en el DAG, pero el proceso no es automático ni trivial. Hay que hacerlo bien, con scripts preparados, sin improvisar.

AG Distribuidos en la nube: promesas, realidades y facturas

Cuando nos movemos a la nube —sea Azure, AWS o cualquier otro proveedor que venda disponibilidad como si fuera pan caliente—, los DAG siguen siendo perfectamente viables, pero el terreno cambia. En Azure, por ejemplo, podemos montar un DAG entre dos regiones usando máquinas virtuales con clústeres de Windows tradicionales o bien utilizando SQL Server en instancias de Azure VM con ILB (Internal Load Balancer) para simular el listener. Lo mismo ocurre en AWS, donde los DAG pueden desplegarse entre zonas de disponibilidad o incluso regiones distintas, aunque allí la gestión de redes, rutas y permisos puede volverse un pequeño infierno si no se domina bien el entorno VPC.

La ventaja clara en la nube es la infraestructura: tenemos latencias razonables entre regiones, almacenamiento redundante, y posibilidad de automatizar el despliegue completo con plantillas (CloudFormation, Terraform u otro, según tus gustos). Pero también hay que tener en cuenta que el coste de mantener dos entornos completos sincronizados no es trivial. Especialmente si se usan discos premium, réplicas activas y tráfico constante entre regiones.

Además, muchos se olvidan de que en la nube no hay testigos compartidos para el quórum, lo que obliga a diseñar bien la lógica de los clústeres para evitar split-brain. Y ojo con los nombres DNS y los certificados: en la nube, los nombres internos de las máquinas cambian, los certificados caducan cuando nadie mira, y el tráfico entre regiones puede requerir ajustes de firewall que no siempre están bien documentados. En resumen: se puede, se debe, pero hay que saber lo que se está haciendo. Porque aquí, equivocarse cuesta dinero. Literalmente.

Otra opción sería tener un AG en local y el distribuido en la nube. De esta manera reducimos costes y tenemos lo mejor de ambos mundos, la infraestructura local controlada y con menor latencia desde nuestra red y la copia segura en la nube replicada casi en tiempo real. Lista para una actuación de emergencia, como ese seguro de viajes que pagas pero deseas no tener que usar nunca.

Cosas que pueden salir mal (y lo harán)

Como todo en SQL Server que involucra clústeres, redes y nombres, hay margen para el desastre elegante. Algunas perlas:

  • Si los certificados no están bien configurados en ambos lados, la réplica forwarder no podrá conectar. Y lo descubrirás justo cuando más prisa tengas.
  • Si los nombres de los nodos se repiten en ambas regiones, los endpoints fallarán y la sincronización no se iniciará.
  • Si los puertos necesarios están bloqueados por firewalls, los AG estarán técnicamente configurados pero no replicarán una coma.
  • Si no documentas el proceso de failover, nadie sabrá qué hacer cuando llegue el momento. Especialmente tú, bajo presión.

Por eso, cualquier DAG serio necesita una prueba completa de recuperación. Hay que simular la caída del entorno primario, validar el failover al secundario, probar el listener, comprobar la latencia, y luego revertir. Si no has hecho esto al menos una vez, tu DAG es una promesa. No una solución.

Conclusión

Un AG distribuido no es para todo el mundo. Tiene complejidad, tiene costes y tiene curva de aprendizaje. Pero si lo que queremos es resiliencia real frente a desastres a nivel de región, y si nuestro negocio no se puede permitir estar horas (o días) sin SQL Server, entonces es una de las mejores inversiones técnicas que podemos hacer.

Eso sí: que nadie lo monte “porque queda bien en el diagrama”. Un DAG sin pruebas, sin documentación y sin monitoreo adecuado es una trampa. Pero bien hecho, es una fortaleza. Una que sigue operativa cuando el resto del castillo se cae.

Y en tiempos de incertidumbre, eso vale más que cualquier SLA firmado con letra bonita.

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 Alta Disponibilidad, Cloud, SQL Server, 0 comentarios

Técnicas de Recuperación ante Desastres (DR) en Always On (AG)

Cuando hablamos de alta disponibilidad en SQL Server, hay un elefante en la sala que muchos prefieren ignorar: la recuperación ante desastres (DR) no es lo mismo que la alta disponibilidad. Y sí, podemos tener un Always On Availability Group en producción, funcionando como un reloj suizo, con réplicas síncronas, listeners con balanceadores bonitos y monitorización con colores llamativos y alertas inmediatas… pero si mañana se prende fuego el CPD o se rompe el clúster de Windows, más nos vale tener algo más que buenas intenciones.

Always On no evita el 100% de los desastres

Empecemos por desmontar un mito recurrente: “Tengo Always On, no necesito backups”. Esta frase existe. La hemos oído. Nos ha dolido. Tener un Availability Group distribuido con tres réplicas no es un sustituto de una estrategia de backup coherente. Es como decir que no hace falta cinturón de seguridad porque llevas airbag. A nivel técnico, los AG están pensados para disponibilidad, no para recuperación. Y desde luego, no protegen contra errores humanos, corrupción lógica ni DROP DATABASE ejecutados por ese usuario avanzado al que le dieron permisos “para que pueda trabajar tranquilo”.

Así que, antes de emocionarnos con réplicas distribuidas y latencias internacionales, empecemos con lo básico.

Los backups si nos salvan ante desastres

Los backups siguen siendo la base de cualquier estrategia de recuperación ante desastres, incluso (y especialmente) cuando usamos Always On. No hay excusa. Y sí, sabemos que hay quien piensa que como tiene tres réplicas en tres regiones, puede dormir tranquilo. Hasta que se borra un dato en la base de datos primaria, y esa operación se replica con precisión quirúrgica a las secundarias. Una especie de ransomware lento y sin rescate.

En un entorno con AG, es fundamental tener claro dónde y cómo hacemos los backups. Idealmente, deberíamos delegar las copias a las réplicas secundarias para liberar carga de la primaria. SQL Server lo permite desde hace varias versiones, y con una correcta configuración de las preferencias de backup, podemos establecer qué réplica se encargará de cada tipo de backup: full, log o copy-only.

Pero cuidado, porque no todas las réplicas valen para todo. Las copias completas deben realizarse en una réplica con acceso legible a la base de datos, y los logs solo en réplicas sincronizadas que reciban todas las transacciones. Además, asegúrate de que el software de backup (si usas uno) es compatible con AG y respeta las preferencias de backup configuradas en el clúster. Hay soluciones “enterprise” que, sorprendentemente, no lo hacen.

Y por si acaso recuerda: sí, seguimos necesitando restaurar las copias de vez en cuando para comprobar que funcionan. Testear la restauración no es una opción, es parte del proceso. ¿Tienes backups diarios? Genial. ¿Los has restaurado alguna vez? Porque si no lo has hecho, lo que tienes son archivos que ocupan espacio, no un plan de recuperación.

AG distribuidos: la aspiración de los ya experimentados en desastres

Si nos tomamos en serio la continuidad de negocio, y el presupuesto lo permite, debemos hablar de Availability Groups distribuidos. Esto no es simplemente una extensión de AGs tradicionales, sino una arquitectura pensada para verdaderas estrategias de recuperación ante desastres geográficamente dispersas. Aquí no estamos hablando de movernos de Madrid a Barcelona, sino de poder perder el centro de datos entero en Frankfurt y que el negocio siga operando desde Dublín sin sudar tinta.

Un AG distribuido se compone de dos (o más) AG independientes que se sincronizan entre sí mediante un listener y una réplica que actúa como puente. Esto implica una configuración más compleja, pero aporta una flexibilidad enorme. Cada lado del AG distribuido puede tener su propio clúster de Windows, su propio quorum, su propia lógica de failover, y no dependen directamente del otro para estar operativos. Es decir, si se rompe todo el AG primario, el secundario puede levantar cabeza por sí mismo, sin necesidad de consultar a nadie. Autonomía total, como un buen DBA cansado de justificarle al jefe por qué no es culpa suya.

Pero no es magia ni es todo tan bonito. Los AG distribuidos no hacen failover automático. Necesitan intervención manual o scripts muy bien preparados, monitorizados y probados. Y además, la sincronización es asíncrona, por lo que hablamos de cierta pérdida de datos en caso de desastre. Aceptarlo o no dependerá del negocio y de su tolerancia al RPO.

Consideraciones adicionales: DR de verdad

¿Todo configurado, AG distribuido listo, backups funcionando? Perfecto. Ahora hablemos de lo que realmente se rompe cuando todo lo demás funciona: la red y el DNS. Porque puedes tener la mejor estrategia del mundo, pero si el listener de SQL no resuelve correctamente en la región de DR, o si el firewall bloquea el puerto de sincronización, todo tu diseño se convierte en una bonita maqueta de PowerPoint.

La recuperación ante desastres es un proceso que debe contemplar todos los componentes, y eso incluye:

  • Que los clientes puedan conectarse automáticamente al entorno de DR sin intervención manual (o con la mínima posible).
  • Que los certificados estén correctamente instalados en todos los nodos si estamos usando encriptación.
  • Que los endpoints estén accesibles, los firewalls configurados y los balanceadores preparados para redirigir tráfico.
  • Que el almacenamiento de backups esté accesible desde ambos lados del AG (o, al menos, replicado adecuadamente).
  • Y más cosas específicas de tu arquitectura que solo tu sabes…

Un test de DR que no valida los nombres DNS, las ACL de red y la resolución de nombres es como una auditoría de seguridad en la que solo se revisan los colores del logo.

Automatización: scripts o muerte

La recuperación ante desastres no debería depender del pulso de una persona que lleva 20 horas despierto. Por eso, automatizar el proceso de failover y recuperación es obligatorio. No deseable. No recomendable. Obligatorio. Y no, no hablo de automatización genérica. Hablo de scripts personalizados para tu entorno, que validen el estado de las réplicas, que ejecuten el ALTER AVAILABILITY GROUP … FAILOVER cuando toque, y que actualicen rutas, registros DNS o configuraciones post-failover si es necesario.

¿Y la documentación? Sí, también es importante. Porque cuando suena el teléfono a las 4 de la mañana, necesitas saber qué hacer y no improvisar con algo que has visto en Stack Overflow o con lo que te ha dicho Chat GPT.

Conclusión

Always On es una herramienta potentísima para mantener la disponibilidad de nuestras bases de datos, pero no sustituye una estrategia de recuperación ante desastres (DR) bien pensada, bien ejecutada y bien documentada. Los backups siguen siendo sagrados. Los AG distribuidos son una bendición si se usan bien. Y los entornos sin pruebas de restauración o sin scripts de failover son simplemente apuestas disfrazadas de arquitectura.

Que un sistema esté “disponible” no significa que esté “protegido”. Y si no lo tenemos claro antes de la caída, lo aprenderemos después. Y no será barato.

¿Recomendación final? Probemos los escenarios de desastre antes de que lo sean. Porque el caos no avisa, pero nosotros sí podemos estar preparados.

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 Alta Disponibilidad, SQL Server, 0 comentarios

Usar siempre dbo en SQL Server: ventajas, riesgos y buenas prácticas

Después de analizar cómo funciona la propiedad db_chainig y los riesgos de activar cross db ownership chaining a nivel de instancia, nos queda un tema que está en el centro de todo: el uso del usuario y esquema dbo de forma sistemática. Es una práctica habitual, cómoda y hasta cierto punto tradicional en SQL Server, pero que conviene revisar con detalle cuando hablamos de seguridad, despliegues controlados y gobernanza de datos.

¿Realmente es buena idea que todo pertenezca a dbo? ¿Qué consecuencias tiene a medio y largo plazo? ¿Dónde está el equilibrio entre comodidad y control?

Qué es dbo y por qué se usa tanto

El usuario dbo (database owner) es un usuario especial en cada base de datos de SQL Server. Está vinculado al propietario real de la base de datos y tiene todos los privilegios dentro de ella. Cuando creamos objetos sin especificar un esquema, y el usuario con el que trabajamos está asignado como dbo, los objetos se crean bajo ese esquema por defecto.

Esto significa que en la mayoría de los entornos, a menos que se especifique lo contrario, todos los procedimientos, tablas, vistas y funciones acaban siendo del esquema dbo y perteneciendo al usuario dbo.

Esta práctica tiene una ventaja clara: evita problemas de permisos y simplifica el acceso a los objetos, sobre todo en proyectos donde no se quiere dedicar tiempo a gestionar esquemas ni propietarios. En resume, es una forma de trabajar directa y suele «funcionar a la primera». Pero también tiene implicaciones importantes que no se deben ignorar.

Seguridad: encadenamiento de propietarios dbo y permisos no deseados

Cuando todos los objetos son propiedad de dbo, es muy fácil que se establezcan cadenas de confianza sin querer. Esto es justo lo que habilita la propiedad db_chainig cuando está activa, y lo que se multiplica peligrosamente si además se activa cross db ownership chaining a nivel de instancia.

Al compartir el mismo propietario, los objetos pueden acceder entre sí sin que se comprueben los permisos del usuario que ejecuta la operación. Esto puede ser deseable en ciertos diseños bien controlados, pero también abre la puerta a que procedimientos maliciosos o mal diseñados escapen a la lógica de seguridad prevista, sobre todo cuando hay múltiples bases de datos con el mismo esquema y propietario.

Además, si todos los objetos son de dbo, resulta más difícil aplicar políticas de control por esquema o restringir accesos según áreas funcionales, ya que todo está en el mismo «cajón».

Mantenimiento y legibilidad: lo que hoy parece fácil con dbo, mañana es un dolor

Usar siempre dbo dificulta la organización lógica de los objetos. Cuando una base de datos empieza a crecer, no hay forma rápida de agrupar o identificar objetos por módulo funcional, equipo responsable o ciclo de vida.

Tampoco ayuda en tareas como generar scripts de despliegue por módulos, aplicar permisos diferenciados según esquema, monitorizar la actividad por subsistemas o delegar administración de partes concretas de la base de datos.

Todo eso requiere una separación explícita por esquemas o, al menos, una política clara de nomenclatura y propiedad. Si todo está bajo dbo, estas tareas se convierten en búsquedas manuales y excepciones constantes.

Auditoría y trazabilidad: todos los caminos llevan a dbo

Desde el punto de vista de la auditoría, tener todos los objetos bajo dbo borra cualquier pista sobre quién creó o modificó qué. El seguimiento de cambios se vuelve opaco, y las herramientas de trazado o revisión de permisos no pueden distinguir entre distintos propietarios lógicos. Esto se agrava si además usamos usuarios compartidos o impersonificación (EXECUTE AS), donde es muy difícil reconstruir el contexto original de ejecución.

Cuando una base de datos es pequeña y la usa un solo equipo, esto puede parecer un problema menor. Pero en sistemas colaborativos, auditados o con cumplimiento normativo, no tener separación de propietarios o esquemas puede ser un problema serio.

Despliegue controlado: lo que no se define, se rompe

Si trabajamos con plantillas de despliegue, versionado de bases de datos o pipelines CI/CD, usar siempre dbo limita la capacidad de definir entornos reproducibles y con permisos granulados. No se puede diferenciar entre objetos internos, públicos, temporales o propios de cada equipo.

Además, algunos errores de despliegue tienen que ver precisamente con suposiciones implícitas sobre el esquema o el propietario: si un script no especifica dbo y el usuario por defecto cambia, el objeto puede terminar en otro esquema, provocando errores sutiles y difíciles de detectar.

¿Cuándo sí tiene sentido usar dbo?

No todo es negativo. Hay escenarios donde usar exclusivamente dbo puede ser razonable. Por ejemplo en bases de datos monolíticas mantenidas por un solo equipo, en proyectos personales o experimentales donde no hay requisitos de seguridad ni mantenimiento a largo plazo o en aplicaciones donde toda la lógica de negocio está encapsulada y no se expone acceso directo a las tablas.

En estos casos, usar dbo reduce fricción y permite concentrarse en el desarrollo funcional. Pero, incluso en estos casos, conviene tener claro que estamos asumiendo una simplificación consciente, no una buena práctica general.

Buenas prácticas recomendadas: ¿dbo si o no?

Si queremos mantener un equilibrio entre simplicidad y control, podemos aplicar algunas de estas pautas.

La primera sería no usar dbo y usar esquemas distintos para separar áreas funcionales, como ventas, compras, auditoria, etc. Especialmente debemos evitar crear objetos como dbo si el usuario final no debe tener control total. En estos casos asignar esquemas a roles o usuarios concretos, y establecer políticas de permisos basadas en ellos es clave. Además, definir el esquema siempre de forma explícita en scripts y objetos programables es imprescindible para que, si un usuario tiene otro esquema por defecto, todo siga funcionando. Por último documenta siempre la política de propiedad y esquema como parte del diseño de cada base de datos.

Con estas simples recomendaciones podrás mantener la claridad y la organización incluso en proyectos con muchos objetos o múltiples desarrolladores.

Conclusión

Usar dbo para todo es cómodo, pero a menudo es una señal de diseño descuidado o sin política de seguridad clara. Aunque puede parecer una solución rápida, a largo plazo complica el mantenimiento, debilita el control de accesos y dificulta la trazabilidad.

En bases de datos pequeñas o entornos cerrados, puede no suponer un problema. Pero si trabajamos en entornos colaborativos, con ciclos de vida largos, requisitos de auditoría o despliegues automatizados, separar esquemas y propietarios deja de ser una opción y se convierte en una necesidad.

No se trata de demonizar dbo, sino de dejar de usarlo como valor por defecto para todo. Definir y respetar una estructura clara es una de las formas más efectivas de asegurar calidad y sostenibilidad en 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, SQL Server, 0 comentarios

Cross DB Ownership Chaining en SQL Server

En el artículo anterior vimos cómo la propiedad db_chainig permite que el encadenamiento de propietarios funcione entre objetos ubicados en bases de datos distintas, siempre que esta opción esté activada en ambas bases de datos y se cumplan ciertos requisitos. Pero hay un aspecto que no abordamos en profundidad: qué ocurre cuando esta configuración se aplica no solo a nivel de base de datos, sino también a nivel de instancia, utilizando la opción cross db ownership chaining. Este ajuste tiene un comportamiento más agresivo y, en la mayoría de los entornos, representa una mala práctica de seguridad que conviene evitar.

¿Qué hace exactamente cross db ownership chaining?

Mientras que la propiedad db_chainig se puede activar o desactivar de forma individual en cada base de datos, la opción cross db ownership chaining es una configuración de instancia que fuerza la activación del encadenamiento de propietarios entre todas las bases de datos de la instancia, sin posibilidad de excluir ninguna.

Activarla equivale, a efectos prácticos, a establecer db_chainig = ON para todas las bases de datos, aunque no lo hayamos hecho explícitamente. Esto significa que cualquier procedimiento, vista, función u otros objetos en una base de datos que comparta propietario con una tabla en otra podrá acceder a ella sin que el usuario tenga permisos explícitos. Y lo más preocupante: este comportamiento se extiende automáticamente a cualquier base de datos nueva que se cree en la instancia.

Cómo activar y desactivar cross db ownership chaining

Podemos consultar el estado actual de la opción con:

Si devuelve valor 1, la opción está activada. Para desactivarla (que es lo recomendable en la mayoría de casos):

Esta configuración requiere nivel de sysadmin, ya que afecta directamente a la seguridad global del motor.

Implicaciones de seguridad

El principal riesgo de mantener esta opción activa es que se rompen los límites de seguridad entre bases de datos. En lugar de tener compartimentos estancos, con cross db ownership chaining se permite el acceso entre objetos de distintas bases de datos con solo compartir el mismo propietario. Esto debilita el aislamiento lógico que SQL Server garantiza por defecto.

Imaginemos una instancia donde convivieran varias bases de datos de distintos departamentos, proyectos o incluso clientes. Si todas ellas utilizan el esquema y usuario dbo, y se activa cross db ownership chaining, cualquier procedimiento mal diseñado o malicioso podría acceder a tablas fuera de su alcance original sin necesidad de permisos explícitos. Este escenario rompe cualquier principio de defensa en profundidad.

Además, si se utilizan funciones como EXECUTE AS, se complica todavía más el análisis de los permisos efectivos, y pueden aparecer brechas difíciles de detectar hasta que ya es tarde.

¿Hay algún caso donde activarla tenga sentido?

La única situación razonable para activar cross db ownership chaining es en entornos completamente controlados, con una única aplicación propietaria desplegada en la instancia, donde todas las bases de datos forman parte de la misma solución y no hay usuarios externos ni terceros ejecutando código dinámico o creando objetos.

Incluso en ese caso, sigue siendo preferible activar db_chainig solo en las bases de datos que lo necesiten, en lugar de aplicar un cambio de instancia que afectará a todo lo que esté ejecutándose ahora y en el futuro.

También puede tener cierta justificación en entornos de desarrollo o pruebas rápidas, donde se valore más la agilidad que la seguridad. Pero ahí conviene recordar que muchas veces lo que se prueba en desarrollo acaba en producción… y con ello los errores de configuración.

Buenas prácticas y recomendaciones

Para mantener la seguridad y el control en nuestras instancias de SQL Server, las pautas más recomendables respecto a esta configuración son claras: “Mantener cross db ownership chaining desactivado por defecto”. Siempre es más recomendable activar db_chainig solo en las bases de datos que lo requieran y siempre de forma explícita y documentada. En cualquier caso, además te recomiendo evitar el uso masivo del propietario dbo en todas las bases de datos, especialmente en entornos con múltiples aplicaciones o proyectos y revisar regularmente qué bases de datos tienen esta propiedad activada y por qué. Tampoco está de más aplicar control de cambios y auditoría cuando se modifiquen opciones de instancia.

Además, en cualquier revisión de seguridad o auditoría formal, tener esta opción activada puede ser motivo de alerta o incluso de no conformidad con normativas como ISO 27001, PCI-DSS o el Esquema Nacional de Seguridad (ENS).

Conclusión

La opción cross db ownership chaining es uno de esos ajustes que, a simple vista, puede parecer útil para evitar errores de permisos durante el desarrollo, pero que en producción representa una puerta abierta a problemas de seguridad difíciles de rastrear. Es una opción de legado que hoy en día solo deberíamos tocar si entendemos perfectamente sus implicaciones.

Si en tu entorno necesitas acceso cruzado entre bases de datos, activa db_chainig solo donde sea estrictamente necesario. Y si lo que quieres es encapsular accesos sin exponer tablas directamente, plantéate usar certificados para firmar procedimientos y mantener un modelo de permisos más seguro y robusto.

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, SQL Server, 0 comentarios

Cómo actúa db_chainig en SQL Server

En su día publicamos un artículo donde analizábamos en profundidad los riesgos de activar la propiedad db_chainig en nuestras bases de datos: db_chainig: una configuración de seguridad peligrosa. Allí abordamos su impacto en la superficie de ataque de una instancia de SQL Server, especialmente cuando se activa de forma global o sin tener un control estricto de propietarios y permisos.

Hoy retomamos el tema con un enfoque diferente. Vamos a mostrar una demo práctica que responde a una duda concreta planteada por un integrante de la comunidad de Telegram “SQL Server Español”, y que nos permite ver de forma clara cómo se comporta esta propiedad cuando varios objetos en distintas bases de datos se relacionan entre sí. Aprovecharé además para precisar algunos matices técnicos que suelen pasar desapercibidos, sobre todo cuando intentamos aplicar el modelo de encapsulación de acceso sin otorgar permisos directos.

Recordatorio: qué es db_chainig y por qué nos debe importar

Como ya explicamos en el artículo de hace meses, db_chainig es una propiedad que habilita el encadenamiento de propietarios entre bases de datos distintas. Cuando está desactivada (valor por defecto), SQL Server impide que un objeto de una base de datos acceda a otro en una base diferente, aunque ambos compartan el mismo propietario y aunque el encadenamiento funcionase sin problema dentro de una única base de datos.

Este comportamiento se introdujo por motivos de seguridad, y su activación requiere un análisis muy cuidadoso. No obstante, existen escenarios legítimos donde permitir este acceso cruzado puede simplificar la arquitectura, como cuando separamos lógica de negocio y almacenamiento físico en distintas bases de datos bajo el mismo control.

La demo: ejemplo de acceso cruzado encapsulado entre bases de datos

Para mostrar cómo se comporta realmente esta propiedad en un escenario típico, he preparado una demo que tenéis disponible aquí.

El entorno consiste en dos bases de datos una con una vista de una tabla de la otra base de datos (podríamos llevarlo al mundo real como una base de datos donde residen los procedimientos que encapsulan la lógica de acceso) y otra base de datos con una tabla (que sería la base de datos donde se encuentran las tablas con los datos reales)

Creamos un usuario solo con privilegios explícitos sobre la base de datos con la vista e intentamos seleccionar la vista que, recordad, lee una tabla de la otra base de datos.

En un primer lugar obtenemos un error porque el usuario no existe en la otra base de datos pero si lo creamos, sin permisos, claro, nos encontramos con otro error porque el usuario no puede acceder a la tabla. 

Hay que recordar que la vista filtra los datos de la tabla por lo que en ningún caso queremos dar al usuario permisos explícitos sobre la tabla, solo debe consultar la información a través de la vista.

Con db_chainig desactivado, la ejecución falla con un error de permisos, incluso si ambos objetos tienen el mismo propietario (dbo). Al activar la propiedad en ambas bases de datos el procedimiento funciona sin que el usuario tenga permisos directos sobre la tabla. Esto demuestra cómo SQL Server evalúa las cadenas de confianza solo si dicha propiedad está activa.

Consideraciones clave sobre propietarios y contexto de ejecución

Uno de los matices más importantes que se observa en la demo es que el encadenamiento entre bases de datos solo se permite si los objetos involucrados tienen el mismo propietario y si la propiedad db_chainig está activa en ambas bases de datos.

Otro detalle importante es que el contexto de ejecución no ha cambiado mediante EXECUTE AS o similar, lo que invalidaría la cadena de confianza.

Esto significa que no basta con activar la propiedad en una sola base de datos. Además, hay que evitar que el procedimiento se ejecute en un contexto que no sea el del usuario propietario de ambos objetos. Este tipo de situaciones no siempre son evidentes y pueden complicar el diagnóstico cuando un procedimiento aparentemente correcto lanza un error de acceso denegado.

Seguridad frente a conveniencia: ¿cuándo tiene sentido usar db_chainig?

Tal y como ya señalamos en el artículo anterior, activar db_chainig a nivel de instancia es algo que deberíamos evitar en la mayoría de escenarios, sobre todo si trabajamos en un entorno multi-tenant o con bases de datos de aplicaciones distintas.

Sin embargo, si tenemos un entorno controlado, donde todas las bases de datos son desplegadas por nosotros, los objetos comparten propietario y los accesos están bien encapsulados, db_chainig puede ser una herramienta útil para simplificar la gestión de permisos y mantener el modelo de mínima exposición.

En ese contexto, lo importante es no relajarse: hay que documentar cada caso en el que se activa, asegurarse de que no hay EXECUTE AS, revisar periódicamente los propietarios de los objetos y evitar cualquier modificación que pueda romper la cadena de confianza sin darnos cuenta.

Alternativas a db_chaining: firma con certificados

Para aquellos entornos donde la seguridad es prioritaria, pero aún así necesitamos encapsular accesos entre bases de datos, lo más recomendable es firmar los procedimientos almacenados con certificados. Esta técnica, algo más compleja de implementar, permite simular una elevación de permisos perfectamente controlada y auditable, sin necesidad de alterar propiedades globales ni confiar en la coherencia del dbo.

Si todavía no has trabajado con este enfoque, te recomiendo investigar cómo funciona la creación de certificados, usuarios basados en certificado y firma de procedimientos. Puedes consultar el artículo que publiqué sobre el tema la semana pasada.

Conclusión

Con esta demo he querido complementar el análisis previo sobre db_chainig, esta vez desde un enfoque más práctico. El comportamiento por defecto protege nuestras bases de datos, pero hay casos reales donde su activación puede facilitar una arquitectura limpia y modular.

Eso sí, hay que entender muy bien sus implicaciones, probarlo a fondo y asegurarnos de que el entorno cumple con los requisitos de seguridad y propiedad para que el encadenamiento funcione sin sorpresas. Y si no queremos depender de esta propiedad, las firmas con certificados siguen siendo la alternativa más elegante y segura.

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, SQL Server, 2 comentarios

Tablas temporales vs. variables de tabla en SQL Server: diferencias que sí importan

Las tablas temporales y las variables de tabla en SQL Server son como los destornilladores y las llaves inglesas de nuestra caja de herramientas: parecidas en concepto, pero con propósitos, comportamientos y peculiaridades bien distintos. Ambos mecanismos nos permiten trabajar con conjuntos de datos intermedios sin necesidad de recurrir a tablas permanentes, pero quien haya intentado usarlos indistintamente en entornos reales sabe que las diferencias importan. Y mucho.

Vamos a destripar ambas opciones con calma, ver cómo se comportan, qué ventajas ofrecen y en qué situaciones conviene (o no) usarlas. Porque sí, aunque parezcan intercambiables, tratarlas como tal suele acabar en consultas lentas, planes de ejecución misteriosos y DBA rezando en voz baja.

Tablas temporales: las inquilinas del tempdb

Las tablas temporales (#TablasTemporales) son lo más parecido a una tabla normal que podemos crear en tiempo de ejecución sin dejar huella permanente. Se crean en la base de datos tempdb, y existen mientras dure la sesión (o el scope) que las creó. Podemos definir índices, claves primarias, restricciones, estadísticas… Vamos, que son tablas de verdad, aunque vivan en alquiler. Su sintaxis es familiar y directa:

O incluso más común aún:

El plan de ejecución que las acompaña suele ser robusto, especialmente si trabajamos con cantidades de datos considerables. SQL Server genera estadísticas automáticas sobre las columnas, lo cual permite un plan más ajustado al volumen real. Esto, que parece un detalle técnico sin importancia, marca la diferencia entre una consulta que vuela y otra que arrastra los pies como yo un lunes por la mañana antes del primer café.

¿Inconvenientes? Algunos. El uso de tempdb implica competencia con otros procesos que también están abusando del mismo recurso. Además, su ciclo de vida depende del contexto: si las creamos en un procedimiento almacenado y lo llamamos varias veces, conviene borrarlas explícitamente con DROP TABLE o usar IF OBJECT_ID(…) IS NOT NULL.

Y por supuesto, cuidado con el scope: una tabla temporal creada dentro de un procedimiento no es accesible desde fuera. Pero eso no debería sorprendernos. Tampoco esperamos que un DECLARE de una variable sobreviva al final del procedimiento.

Variables de tabla: pequeñas, rápidas… y caprichosas

Las variables de tabla (@VariablesDeTabla) se introdujeron como una forma rápida y elegante de manejar pequeños conjuntos de datos sin el overhead de una tabla temporal completa. Son ideales para almacenar unas cuantas filas, iterar lógicamente sobre ellas o devolver resultados simples.

La sintaxis es limpia:

Y su ciclo de vida es exactamente el del bloque donde se declaran. No hay que preocuparse por borrarlas ni por interferencias externas. Hasta aquí todo bien.

Ahora viene el problema: SQL Server no genera estadísticas sobre variables de tabla. Nunca. Ni en 2008 ni en 2022. Esto significa que el optimizador trabaja a ciegas. Literalmente: asume que una variable de tabla tiene una única fila. Da igual si tiene 1 o 10.000. El plan de ejecución será el de una tabla de una fila. Y eso, amigos, rara vez termina bien.

¿Hay excepciones? Desde SQL Server 2019, con OPTION (RECOMPILE), el optimizador puede estimar el número real de filas en algunos casos. Pero es una tirita en una fractura abierta. A veces ayuda, otras no. Y seguir usándolas a ciegas es una receta para la frustración.

¿Entonces son inútiles? No, ni mucho menos. Funcionan de maravilla cuando el número de filas es pequeño (menos de 100 suele ser seguro) y cuando las operaciones son simples. Pero si metemos un JOIN, un GROUP BY o empezamos a empujar lógica compleja… mejor sacar la artillería de verdad: tabla temporal.

Tablas temorales vs Variables de tabla: lo que no te dice la documentación

Hablemos claro. Las diferencias no están solo en la sintaxis o el ámbito. Lo importante es cómo se comportan bajo carga, cómo afectan al plan de ejecución y qué tipo de mantenimiento requieren. Para compararlas vamos a ver uno a uno los aspectos más interesantes.

Estadísticas

Las tablas temporales sí generan estadísticas; las variables de tabla no. Esto significa que las temporales permiten planes de ejecución más óptimos en escenarios con muchos datos. Las variables, no.

Soporte de índices

Ambas opciones permiten claves primarias y restricciones únicas. Desde SQL Server 2014 es posible definir índices secundarios en variables de tabla, pero solo dentro de la declaración y con sintaxis limitada. En tablas temporales podemos crear cualquier tipo de índice, incluidos los columnstore, sin restricciones adicionales.

Transacciones

Las variables de tabla no se ven afectadas por ROLLBACK. Si algo falla, su contenido sigue ahí, lo cual puede ser bueno… o un bug encubierto. Las tablas temporales, en cambio, participan en las transacciones como cualquier otra tabla.

Almacenamiento y persistencia

Ambas opciones viven en tempdb, aunque las variables lo hagan de forma menos visible. Pero a nivel físico, no hay magia: no están «en memoria», como algunos aún creen. Eso sí, las temporales suelen dejar más rastro en el sistema de archivos si no se gestionan bien.

Además, como ya hemos comentado las tablas temporales duran lo que dura la sesión, es decir, mientras no las borremos o cerremos esa sesión seguirán ahí. Las variables tipo tabla, por el contrario duran lo que dura la ejecución del lote (batch).

Si veis en la imagen, la segunda consulta no encuentra nada. Esto pasa porque después del “GO” ya se considera otro lote.

Paralelismo

Las tablas temporales pueden beneficiarse del paralelismo en las consultas; las variables de tabla, salvo casos contados y versiones muy recientes de SQL Server, no.

Lectura y escritura

En escenarios de alto volumen, las operaciones sobre variables de tabla pueden ser considerablemente más lentas que sobre tablas temporales. Aunque el coste del DECLARE parezca nulo, el impacto acumulado en los planes de ejecución mal optimizados se paga caro.

Casos de uso, ¿Cuándo elegir tablas temporales o variables de tabla?

Una variable de tabla nos viene de perlas cuando queremos devolver una pequeña tabla desde una función, cuando estamos en mitad de un script complejo que necesita guardar una docena de valores intermedios, o cuando buscamos claridad sin sacrificar rendimiento (porque sabemos que los datos son pocos y controlados). Por norma general, no deberíamos usarlas para más de 100 registros.

Una tabla temporal brilla en todo lo demás: cargas intermedias, transformaciones complejas, conjuntos de datos que van a vivir varias etapas, o cuando necesitamos analizar y refinar el rendimiento de una consulta. Incluso para esas subconsultas que usamos varias veces en una misma consulta y pueden llegar a ser pesadas.

También conviene recordar que hay un tercer actor en esta historia: las tablas temporales globales (##TablaGlobal) y las tablas de memoria (MEMORY_OPTIMIZED). Pero eso ya es otro capítulo. O varios.

Conclusión

Elegir entre una tabla temporal y una variable de tabla no debería depender del estado de ánimo, sino del uso que le vamos a dar. Si los datos son escasos, la lógica es sencilla y no necesitamos estadísticas ni índices complejos, la variable funciona. Pero si hay que unirse a otras tablas, mover volumen o exprimir rendimiento, la tabla temporal es la opción profesional.

No olvidemos que el optimizador de SQL Server toma decisiones basadas en lo que sabe. Y con una variable de tabla, lo que sabe es poco. Si le damos una tabla temporal bien definida, con índices y estadísticas, puede hacer su trabajo. Si le damos una caja cerrada con un «ya te apañarás», no esperemos milagros.

Así que, la próxima vez que tengamos que elegir entre DECLARE @Tabla y CREATE TABLE #Temp, pensemos dos veces. Porque sí, ambas pueden almacenar datos. Pero sólo una de ellas está preparada para aguantar una jornada completa sin pedir un café doble a mitad de camino. Y no, no es la variable.

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