Rendimiento

Nueva caché de seguridad en SQL Server 2025

Llevamos ya tiempo con la preview de SQL Server 2025 probando todas las novedades. La lista es larga y, a veces, cuesta distinguir entre lo realmente útil y lo puramente decorativo. Entre tanto brillo marketiniano, hay una mejora de la que no se ha hablado, que muchos pasarán por alto sin comprender las implicaciones, pero que a mi me ha hecho sonreír y decir: “Ya era hora”. Os hablo de la nueva capacidad de invalidar cachés de seguridad de forma específica por inicio de sesión en SQL Server 2025. Y sí, es tan buena como suena.

¿Qué es esto de la caché de seguridad?

Antes de meternos en harina, conviene recordar qué es exactamente esa “caché de seguridad” que ahora Microsoft ha afinado. Cuando un usuario se conecta a SQL Server, el motor evalúa qué permisos tiene para acceder a objetos, ejecutar procedimientos, ver datos… ya sabéis, lo básico para evitar que todo sea un buffet libre de SELECT * FROM SensitiveTable.

Como no somos tontos (y SQL Server tampoco), esta validación no se repite cada vez que alguien lanza una consulta. Sería un suicidio en términos de rendimiento. En su lugar, SQL Server guarda esa información en memoria (en la famosa security cache) y la reutiliza mientras no haya cambios que invaliden su contenido.

¿El problema? Hasta ahora era muy sensible. Si cambiabas cualquier permiso de cualquier usuario (cambio de permisos, modificación de roles, o revocar un acceso), se eliminaban todas las entradas DE TODOS LOS USUARIOS. Esto, por supuesto, tiene efectos inmediatos en el rendimiento de cualquier sesión abierta, aunque no tuviera nada que ver con el cambio.

Vamos, que tirábamos la caché como quien reinicia un servidor por si acaso: por pura desesperación.

SQL Server 2025 trae cordura: invalidación específica por login

Con la llegada de SQL Server 2025, se acabó el “todo o nada”. Ahora, cuando se invalidan entradas de la caché de seguridad debido a un cambio en los permisos, el sistema es lo bastante listo como para borrar solo las entradas correspondientes al login afectado. El resto permanece intacto.

Esto supone una mejora directa en varios frentes. Para empezar, reduce el impacto de cualquier cambio de seguridad. No hay invalidaciones masivas innecesarias, no se resienten las sesiones de otros usuarios, y la CPU no se dispara validando de nuevo cientos o miles de entradas de permisos para conexiones que no han cambiado ni una coma de sus privilegios.

¿Por qué esto importa? Rendimiento, escalabilidad y menos sustos

Puede parecer que un cambio de estas características no tiene mucha importancia, y así es entornos con pocos usuarios y permisos bastante genericos. Pero cuando el volumen de usuarios y la granularidad de los permisos son considerables, la diferencia entre invalidar toda la caché de seguridad y hacerlo de forma selectiva puede marcar la diferencia. En entornos con cientos o miles de sesiones concurrentes, la diferencia es tan evidente como entre ejecutar SELECT con un índice… o sin él.

Antes, un cambio puntual en los permisos podía convertirse en una mini tormenta de validaciones. La CPU subía, la latencia aumentaba, y tú te encontrabas explicando por qué un GRANT a las 9:30 había dejado la aplicación más lenta que un Access con macros durante unos minutos. Todo eso queda en el pasado con esta nueva implementación.

Ahora, si revocas un permiso a un usuario que ya estaba conectado, SQL Server se limita a eliminar sus entradas específicas de la caché. El resto de usuarios ni se enteran. Y tú tampoco tendrás que revisar gráficos de rendimiento preguntándote qué demonios ha pasado.

Cambios de roles, miembros de grupos y lo que siempre duele

Uno de los escenarios donde esto brilla especialmente es cuando se hace una modificación en roles o membresías de grupos. Añadir o quitar a alguien de un db_datareader, por ejemplo, solía ser sinónimo de purgar toda la caché de seguridad.

Con SQL Server 2025, eso se acabó. La limpieza de la caché se ciñe a ese login concreto, incluso si el cambio afecta a una membresía en roles de servidor o roles personalizados. Menos interrupciones, menos recompilaciones internas, y más estabilidad.

Que sí, que aún quedan muchos elementos que provocan recompilaciones y limpiezas de caché que no siempre tienen sentido, pero al menos aquí han puesto orden en una de las áreas más olvidadas por el motor en versiones anteriores.

¿Cómo saber si está funcionando?

No hay un nuevo DMV mágico que diga “estás disfrutando de la nueva caché de seguridad personalizada”, pero si monitorizas el uso de CPU y el acceso concurrente durante cambios de permisos, deberías notar una mejora clara. Sobre todo en sistemas con mucha actividad concurrente y una gestión de seguridad activa.

Y si eso no te vale y quieres verlo con tus propios ojos siempre nos quedarán los eventos extendidos, esa magnífica herramienta que lo captura todo. Puedes crear una sesión que capture los nuevos eventos “login_token_cache_hit” que se producen cuando el token de la caché de seguridad sigue activo y el evento “login_token_cache_miss” que es cuando el token de la caché no es válido y hay que generar una nueva entrada.

Demo caché de seguridad 

Vamos a comprobar que esto realmente funciona. Para ello tenemos nuestros logins con ID 267 y 268 y vamos a crear una sesión de xEvents que capture los eventos que hemos comentado antes:

Lo primero que vamos a hacer es borrar la caché de seguridad:

Como hemos borrado la caché, estas dos primeras entradas generan un evento “login_token_cache_miss”, no existe registro en la caché. 

Pero, si volvemos a conectarnos veremos ya los hit, es decir ha utilizado el token existente en caché

Ahora vamos a cambiar los permisos de uno de los logins

Y al volver a conectar veremos solo uno de los dos logins tiene el miss y el otro mantiene su token válido (evento hit). Además veís en la captura que yo he añadido tambien los eventos “security_cache_login_timestamp_increment” a mi captura de eventos, que me indica cuando se ha producido un cambio de permisos.

¿Qué implicaciones tiene para nosotros como DBAs?

Básicamente, nos devuelve un poco de control. Ahora podemos aplicar cambios de seguridad sin tener miedo a provocar un alud de recompilaciones y penalizaciones de rendimiento. Se acabó el tener que programar revocaciones de permisos fuera del horario laboral o acompañarlas de una explicación de daños colaterales.

También nos da más seguridad en entornos de desarrollo y pruebas. Podemos simular escenarios de cambios de permisos sin el temor a que medio entorno colapse por culpa de una caché global destruida innecesariamente.

Eso sí, no todo es perfecto. La documentación oficial todavía no entra en muchos detalles sobre cómo se comporta esta nueva caché con escenarios complejos de impersonación (EXECUTE AS), certificados o permisos a nivel de esquema. Habrá que investigar (y ya lo haré en otro artículo si me lo pedís) si este comportamiento selectivo se extiende también a esos casos.

Conclusión

La invalidación selectiva de la caché de seguridad en SQL Server 2025 es una mejora tan lógica que sorprende que no estuviera ya implementada hace años. Pero aquí está, y funciona como debe. Nos da más precisión, menos impacto colateral y permite cambios de seguridad sin temor a convertir el servidor en una verbena de validaciones.

Como siempre, no es magia. Si haces cambios absurdos o con prisas, te seguirás metiendo en líos. Pero al menos, ahora, el motor te lo pone un poco menos difícil. Y eso, en este mundo de permisos, roles y DBA que no duermen, ya es bastante.

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

Especial Halloween. El marrón que todo DBA ha sufrido

¿Qué Halloween da miedo? Será para los que no han tenido que restaurar un backup en producción y estaba corrupto, con el jefe respirándoles en la nuca y un SLA expirando más rápido que el café enfriándose.

Los verdaderos horrores no salen en películas. Se ejecutan en nuestros servidores.

Si el año pasado nos pusimos nostálgicos para hablar del problema de Halloween original, hoy vamos a hablar de jobs fallidos, bloqueos eternos, desarrolladores con acceso a sysadmin, y scripts “probados en otro entorno”. Marrones que un DBA conoce muy bien. Marrones que no se borran con un ROLLBACK.

Definición técnica

MARRÓN (noun)

Término operativo usado en entornos técnicos para describir cualquier tarea, incidente o requerimiento que:

  1. No estaba prevista.
  2. Nadie quiere hacer.
  3. Tiene alta visibilidad y cero documentación.
  4. Requiere acción inmediata (generalmente ayer).
  5. Y suele implicar que el culpable eres tú, aunque no tengas ni idea de qué ha pasado.

Roles asociados:

  • Enmarronador (BrownDispatcher): Individuo que asigna el marrón con una sonrisa, un café en la mano o un “esto es rápido”. Suele tener cargo, pero no responsabilidad.
  • Enmarronado (Browned): Víctima del proceso de asignación. También conocido como “el de SQL” o “el que sabe”. No necesariamente tiene culpa, pero sí marrón.
  • Buscamarrones (BrownFinder): Persona que se ofrece voluntaria “para aprender” o “echar una mano”. A menudo desaparece misteriosamente cuando el marrón explota.
  • Comemarrones (BrownEater): DBA veterano que se ha comido tantos marrones que ya solo le quedan dos emociones: resignación y café.

Importante:

El marrón flotante: la petición que no llega (pero llegará)

Es lunes y alguien menciona “tenemos que mirar lo del rendimiento del ERP” mientras tú estás con otras 40 cosas. Nadie lo documenta, nadie lo asigna, pero ya sabes lo que va a pasar. Lo oyes flotar.

Un día (viernes a última hora, seguro) alguien abre un ticket con prioridad alta y asunto ambiguo: “Problema con SQL”. Ni reproducible, ni claro. Y para cuando llega a ti, ya eres el responsable. Del ERP. Del rendimiento. De todo.

Este marrón huele a cursores usados alegremente por algún genio que ha leído un blog equivocado. Y te va a tocar explicarlo. Otra vez.

El marrón fulminante: el «¿qué ha pasado?» a las 8:00

Son las 7:58. Te conectas. Parece que todo está tranquilo. Hasta que alguien grita por Teams: “¡la base de datos está caída!”

Miras los logs. Alguien reinició el servicio de SQL Server durante la noche. ¿Motivo? “Estaba lento y pensé que eso lo arreglaría, luego el servicio no se paraba y reinicié el servidor”. 

No sabemos qué ha pasado, solo tenemos aplicaciones paradas y usuarios locos por los pasillos.

Y tú, desayunando con una base de datos de 25 Tb en recuperación.

Este es el marrón que se instala sin pedir permiso. Lo único que puedes hacer es ponerte los guantes de forense, y rezar para que pase cuanto antes.

El automarrón: lo hiciste tú, y lo sabes

Hay veces que el marrón no viene de fuera. Te lo cocinas tú solito.

Aceptaste esa migración “sencilla” de SQL Server 2012 a 2022. Te dijeron que solo había que mover “un par de bases”. Ahora estás descubriendo jobs con código T-SQL del pleistoceno, linked servers a dominios que ya no existen, y stored procedures que funcionan por magia negra.

Y todo tiene que estar listo este fin de semana. Por supuesto.

Es el automarrón. Y el problema no es el marrón. Es tu optimismo que te llevó a no mirar dos veces.

El marrón pata negra: ese proyecto que recordarás siempre

Hay marrones, y luego está ese proyecto que te cambió la vida. El que te hizo cuestionarte tus decisiones vitales.

Un data warehouse mal diseñado que hay que “reoptimizar”. Con cientos de tablas de millones de registros sin índices, y vistas anidadas que ya tienen su propio ecosistema. Con consultas que tardan horas y desarrolladores que te juran que “antes iba rápido”.

Es el marrón pata negra. No se arregla. Se sobrevive. Y si logras salir de ahí, probablemente acabarás con un tic nervioso… y un máster en tuning sin quererlo.

El marrón de última hora: el clásico de viernes tarde

Viernes, 14:59. Recoges. Cierra sesión. Y entonces… “oye, una cosilla antes de que te vayas”.

Spoiler: no es una cosilla.

Es un cambio en producción. Un script que nadie ha revisado. Un MERGE que te juran que va bien “porque lo hemos probado en dev”. Unos índices que hay que “crear rapidito” porque el CTO ha leído en LinkedIn que eso mejora el rendimiento.

Y tú, con el abrigo puesto, ejecutando con miedo un script que viene de un Excel. Bienvenido al marrón invocado. No saldrás antes de las 21:00. Si sales.

El marrón mutante: el que cambia cada día

Te asignan un problema de rendimiento. Miras. Optimización sencilla. Pones un índice. Va mejor.

Pero luego cambia el plan de ejecución. Luego te enteras de que han cambiado el MAXDOP sin avisarte. Luego la tabla crece un 300% de un día para otro. Y el problema vuelve. Peor.

El marrón mutante nunca termina. Hoy es CPU, mañana IO, pasado bloqueos. Intentas aplicar parches, pero no hay final. Es como dar soporte a una base que se autodestruye a diario y se recompone… peor.

Vives en un entorno hostil.

El marrón sonda: el disfrazado de consulta inocente

“Una duda rápida sobre un procedimiento que tarda un poco…”

Error. Ya estás dentro.

Empieza como una duda. Luego te piden revisar el plan. Luego optimizar. Luego reescribir. Luego hacer un informe. Luego… estás haciendo tú todo.

Los marrones sonda son los peores porque son invisibles. Te atrapan por empatía. No porque puedas decir que no, sino porque ya estás en medio. Y claro, ya que estás…

El pressing brown: presión en estéreo

Cliente cabreado. Jefe nervioso. Equipo de desarrollo esperando. Todos preguntan. Todos presionan.

Y tú, el DBA, recibiendo por todos lados. Con logs, sin contexto, y con el “esto no puede estar fallando, si no hemos tocado nada” como único diagnóstico.

Es el pressing brown. Nadie lo admite, pero todos lo han hecho: tirar el marrón al de bases porque “seguro que es algo del SQL”.

Y a ti te toca arreglarlo. Sin información. Sin culpa. Sin gloria.

El brown shower: todo cae a la vez

Backup corrupto. Alerta de disco. AG desincronizada. Login bloqueado. Limpieza de datos que ha borrado datos de más (a quien se le ocurre poner las FK con borrado en cascada…). El entorno ha dicho basta. Y todo a la vez.

Eso no es un marrón. Es un brown shower.

Cuando pasa, no arreglas. Contienes. Priorizas, sobrevives, y rezas porque el clúster no decida reiniciarse. Y si alguien pregunta cómo va todo, solo di: “controlado”, mientras lloras por dentro.

Conclusión: el terror real se ejecuta en SQL

Que sí, que Halloween da miedo. Pero no tanto como ejecutar un DELETE sin WHERE en la base de producción, o que el backup del FULL no incluya las bases más críticas.

Nosotros no necesitamos sustos. Ya los trae el trabajo.

Y recuerda: si un jefe te dice “es una tarea rápida”, asegúrate de tener a mano tu última copia del CV actualizado. Y una linterna. Porque se viene noche larga.

Feliz Halloween, compañeros de marrones. Que los browners pasen de largo… o al menos os pillen con un buen plan de contingencia.

Publicado por Roberto Carrancio en Otros, 0 comentarios

OPTIMIZED SP_EXECUTESQL: Novedad de SQL Server 2025

Con la llegada de SQL Server 2025, Microsoft introducirá una serie de mejoras orientadas a optimizar el rendimiento del motor. Una de ellas es la nueva configuración OPTIMIZED_SP_EXECUTESQL, pensada específicamente para entornos que hacen uso intensivo de SQL dinámico a través de sp_executesql. En este artículo profundizo en su funcionamiento, cómo activarla, qué impacto tiene en la caché de planes y cómo se comporta bajo carga concurrente.

Contexto: el problema con sp_executesql y el plan cache

Cuando ejecutamos consultas dinámicas con sp_executesql, especialmente en entornos con alta concurrencia, SQL Server puede compilar múltiples planes para lo que, conceptualmente, es la misma consulta. Aunque el texto del lote (batch text) sea idéntico y se usen parámetros, el compilador no siempre consigue identificarlo como la misma ejecución, lo que termina generando entradas repetidas en la plan cache.

Esto da lugar a varios problemas conocidos:

  • Bloat en la plan cache, con decenas o cientos de planes similares almacenados.
  • Consumo innecesario de CPU por compilaciones redundantes.
  • Contención en la compilación, cuando múltiples sesiones intentan compilar la misma consulta al mismo tiempo.

Con OPTIMIZED_SP_EXECUTESQL, SQL Server introduce un nuevo mecanismo para mitigar estos efectos.

¿Qué es OPTIMIZED SP_EXECUTESQL?

Se trata de una configuración a nivel de base de datos que se encuentra desactivada por defecto y que puede activarse mediante ALTER DATABASE SCOPED CONFIGURATION. Su objetivo principal es optimizar la forma en que SQL Server gestiona la compilación y almacenamiento en caché de planes asociados a ejecuciones de sp_executesql.

Cuando se activa esta opción, el comportamiento cambia significativamente:

  • La primera ejecución de un lote dinámico mediante sp_executesql compila el plan normalmente.
  • Otras sesiones concurrentes que ejecutan el mismo lote esperan a que finalice la compilación.
  • Una vez compilado, todas las sesiones reutilizan el mismo plan, del mismo modo que lo harían si fuera un procedimiento almacenado.

Requisitos y dependencias

Lo primero, obviamente, es tener SQL Server 2025 y tu base de datos en un nivel de compatibilidad 170. Además, si en tu base de datos tienes activada la opción de actualización automática de estadísticas, Microsoft recomienda habilitar también ASYNC_STATS_UPDATE_WAIT_AT_LOW_PRIORITY (más bien es un requisito pero, ¿has visto qué bien me ha quedado lo de “Microsoft recomienda”?). Esto asegura que el nuevo comportamiento no introduzca contención innecesaria durante las actualizaciones estadísticas, en escenarios de alta concurrencia.

SP_EXECUTESQL

Cómo activarlo

Para habilitar la funcionalidad, puedes ejecutar el siguiente bloque:

Recuerda, necesitas estar en nivel de compatibilidad 170 (SQL Server 2025) para que la opción sea válida.

Puedes comprobar el estado actual de la configuración con:

Demostración práctica

Vamos a ejecutar una serie de pruebas en una base de datos StackOverflow (modo de compatibilidad 170) para observar el impacto real de esta configuración en la plan cache.

Paso 1: Asegurar que la opción está desactivada

Paso 2: Limpiar la caché de planes

Paso 3: Ejecutar carga concurrente

Usaremos SQLQueryStress para lanzar la siguiente consulta, que ejecuta sp_executesql de forma concurrente:

Parámetros en SQLQueryStress:

  • Iteraciones por hilo: 10
  • Número de hilos: 100

Esto generará 1000 ejecuciones concurrentes de la misma consulta dinámica.

Paso 4: Analizar la plan cache

Una vez completadas las ejecuciones, inspeccionamos el número de planes generados:

Resultado esperado (sin optimización): múltiples planes distintos (en pruebas reales, se observan entre 20 y 30 para este escenario), aunque la consulta sea la misma.

Esto evidencia el comportamiento ineficiente por defecto: múltiples planes para la misma carga.

Paso 5: Activar la optimización

Paso 6: Limpiar de nuevo la caché

Paso 7: Ejecutar la misma carga

Volvemos a lanzar los 100 hilos concurrentes con SQLQueryStress, exactamente como antes.

Paso 8: Analizar resultados

Ejecutamos de nuevo la consulta sobre la plan cache:

Resultado esperado (con optimización): una sola entrada en la caché de planes, con una execution_count acumulada de 1000. El compilador ha tratado la consulta dinámica como si fuese un procedimiento almacenado.

Este comportamiento elimina de raíz el bloat en la caché y evita la compilación paralela.

¿Qué hace SQL Server exactamente?

El mecanismo detrás de esta optimización replica el modelo clásico de los procedimientos almacenados:

  1. La primera ejecución de una consulta concreta compila el plan.
  2. El resto de ejecuciones esperan a que ese plan esté disponible.
  3. Una vez compilado, todas las ejecuciones reutilizan ese mismo plan.

Este comportamiento garantiza una mayor eficiencia tanto en uso de CPU como en gestión de memoria. Ya no veremos un plan por cada sesión, sino un único plan compartido y referenciado por todas.

Consideraciones finales

Este cambio solo aplica a sp_executesql. No afecta a EXEC() ni a otros mecanismos de ejecución dinámica.

Las consultas deben ser realmente idénticas (texto y parámetros) para que se detecte la coincidencia.

Si tu aplicación genera SQL dinámico con pequeñas variaciones en los literales o estructura, el beneficio será menor.

La mejora se aprecia especialmente en entornos con alta concurrencia o patrones repetitivos.

Conclusión

OPTIMIZED_SP_EXECUTESQL es una de las mejoras más importantes en la gestión del plan cache que hemos visto en años. Su activación puede suponer una diferencia notable en servidores que sufrían problemas de rendimiento por exceso de compilaciones o saturación de memoria con planes efímeros.

Es una de esas configuraciones que, bien aplicada, no solo mejora el rendimiento, sino que permite aprovechar mejor los recursos existentes. No es una solución mágica, pero sí una herramienta eficaz para un problema conocido.

Si trabajas con aplicaciones que generan SQL dinámico intensivo y tienes pensado actualizar SQL Server 2025 cuando sea estable, este cambio debería estar en tu lista de tareas prioritarias.

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

Database Snapshots en SQL Server: Ni backup, ni milagro, pero muy útil

Llevábamos ya años con el blog y sin hablar de snapshots. Quizá porque es una de esas funcionalidades que están ahí desde hace años (SQL Server 2005, nada menos), pero que siempre han vivido en esa zona gris de lo útil pero olvidado. Como ese índice XML que alguien creó en 2013 y nadie ha tocado desde entonces. Hoy vamos a remediarlo, no para darles bombo, sino para entender realmente qué ofrecen, qué limitaciones arrastran, y sobre todo, cuándo tiene sentido usarlos… y cuándo no.

¿Qué es un Database Snapshot?

Un Database Snapshot es una copia solo lectura de una base de datos en un punto en el tiempo. No es una copia física, ni tampoco un backup, aunque mucha gente los confunda (mal hecho). Es un mecanismo basado en copy-on-write que permite mantener la imagen original de los datos a medida que la base activa cambia.

No crea una copia completa de los datos. En lugar de eso, guarda las páginas modificadas en un archivo sparse, lo que permite “reconstruir” cómo estaban los datos en el momento del snapshot sin necesidad de duplicar todo el almacenamiento.

Importante: el snapshot depende completamente de la base de datos original. Si la base cae, se corrompe o desaparece, el snapshot no vale absolutamente para nada. Cualquier parecido con un backup es pura coincidencia y mala comprensión técnica.

¿Cómo funciona internamente?

El principio es simple, en el momento en que se crea un snapshot, SQL Server marca todas las páginas como estables. A partir de ese instante, cada vez que una página de datos va a ser modificada en la base de datos original, su contenido anterior se copia en el archivo sparse del snapshot. Esto es el famoso copy-on-write.

Por eso, al consultar un snapshot, SQL Server reconstruye cada página accediendo al archivo sparse solo si esa página ha cambiado. Si no, la lee directamente de la base original. Esta eficiencia hace que los snapshots sean rápidos de crear y razonablemente económicos en almacenamiento… al menos al principio.

Ahora bien, si la base de datos se modifica mucho, los archivos sparse pueden crecer de forma nada despreciable. A efectos prácticos, un snapshot puede acabar ocupando casi tanto como la base original si hay suficiente actividad. No es frecuente, pero tampoco impensable.

Sintaxis básica 

Supongamos que tenemos una base de datos llamada MiBase y queremos crear un snapshot. Es así de fácil:

Casos reales de uso

Los snapshots tienen usos muy específicos. Aquí van algunos que sí tienen sentido técnico.

1. Restauración rápida tras una operación peligrosa

Antes de hacer un update masivo, un truncate o cualquier otro acto temerario, puedes crear un snapshot. Si algo sale mal, puedes volver al estado anterior usando un revert.

Eso sí, este RESTORE elimina todos los cambios hechos desde que se creó el snapshot. Nada de granularidad. Esto es todo o nada. 

2. Consultas analíticas en entornos OLTP

A veces necesitas lanzar un informe o validación sin que los datos cambien mientras se ejecuta. Y no, no siempre puedes meter todo en una transacción ni usar niveles de aislamiento elevados sin liarla en el entorno OLTP.

Ahí es donde un snapshot puede tener sentido. El snapshot genera una imagen coherente y estable de los datos en el momento de su creación. Puedes hacer consultas complejas sin riesgo de leer datos a medias ni provocar bloqueos.

Pero que no te vendan la moto, el snapshot no reduce la carga del sistema. Las páginas que no han cambiado desde su creación se siguen leyendo desde la base original. El I/O sigue yendo a los mismos discos. Incluso puedes añadir algo más de carga por el copy-on-write si la base está escribiendo mucho.

¿Quieres estabilidad en tus lecturas? Perfecto.
¿Quieres rendimiento? Haz otra cosa.
Por ejemplo:

Tendrás una lectura coherente, congelada en el tiempo, sin preocuparte de cambios concurrentes. Pero no esperes milagros en los tiempos de respuesta.

3. Comparaciones entre versiones

Ideal si necesitas comparar el estado de los datos antes y después de una carga o transformación. Puedes leer ambos mundos (activo y snapshot) en paralelo, por ejemplo:

O comparar registros concretos, detectar cambios en columnas, o revisar cuántos registros nuevos hay que no existían en el snapshot. Todo sin afectar a la base activa.

4. Testing rápido

En entornos de pruebas donde necesitas una copia coherente y estática para validar un proceso, sin necesidad de clonar toda la base.

Limitaciones que no conviene ignorar

Los snapshots no son mágicos. Y como todo lo que parece demasiado cómodo, tienen letra pequeña. Aquí van algunas verdades que conviene tener presentes:

  • Solo lectura. No se pueden modificar. Olvídate de hacer pruebas de escritura ahí dentro.
  • Vinculación absoluta a la base original. Si la base cae, se va el snapshot con ella. No es replicable, no es portable, y desde luego, no es “seguro”.
  • No puedes hacer backup de un snapshot. Ni exportarlo fácilmente. Vive y muere en el servidor que lo contiene.
  • No están soportados en Azure SQL Database. Aunque sí en SQL Server en Azure VMs. Si estás en PaaS, olvídate.
  • Limitación de cantidad. No hay una cifra oficial, pero no abuses. SQL Server no está pensado para mantener docenas de snapshots activos a la vez.

Y sí, pueden afectar al rendimiento. Pero esto merece su propia sección…

El coste en rendimiento

Una de las mayores falacias con los snapshots es que «como no copian todos los datos, no afectan al rendimiento». Bueno, sí, y los triggers tampoco afectan si no se disparan nunca. Vamos al grano.

El impacto de los snapshots no está en la creación inicial, eso es casi instantáneo, sino en lo que pasa después, en cuanto la base de datos empieza a cambiar. Cada vez que se modifica una página en la base activa, SQL Server tiene que hacer una copia previa en el archivo sparse del snapshot. Esto añade una operación de escritura adicional por cada modificación.

¿Y eso qué implica? Más I/O. Más presión sobre el subsistema de almacenamiento. Y si no tienes discos NVMe, una SAN generosa o un almacenamiento SSD con margen, vas a notarlo. No al minuto uno, pero lo vas a notar.

En sistemas con alta tasa de escritura (bases OLTP vivas, sincronizaciones frecuentes, cargas masivas…), ese copy-on-write puede convertirse en un cuello de botella silencioso. No suele romper el sistema, pero lo frena. Y lo hace justo cuando menos te interesa: en plena operación intensa.

Lecturas extra, carga extra

Otra consecuencia menos obvia, al hacer lecturas desde el snapshot, SQL Server tiene que reconstruir cada página accediendo a dos ubicaciones posibles (la base original o el archivo sparse). Esto añade complejidad interna a la lógica de lectura, aunque el impacto sea menor que en escritura.

¿Quieres pruebas? Basta con monitorizar I/O cuando un snapshot está activo y tu base de datos empieza a recibir carga. Puedes usar sys.dm_io_virtual_file_stats, perfmon o herramientas de terceros como Redgate SQL Monitor. Verás cómo crece la escritura en el archivo sparse, y con ello, la latencia de las operaciones normales.

Y por supuesto, más archivos significa más trabajo para el planificador de I/O de SQL Server. En entornos con varias bases y múltiples snapshots, el impacto se acumula. No es dramático si lo controlas, pero si te dedicas a crear snapshots como quien colecciona Pokémon, vas a pagar el precio.

En resumen: los snapshots no son gratis. Cuestan I/O, y ese coste crece con el tiempo y con la actividad. Por eso no deben dejarse activos más de lo necesario, ni usarse como sistema “por si acaso”. Ese «por si acaso» puede ser el motivo por el que tus discos van al 90% sin razón aparente.

Conclusión

Los Database Snapshots son útiles. Mucho. Pero solo si se usan con cabeza. No sustituyen backups, no mejoran el rendimiento por arte de magia, y desde luego, no están hechos para vivir en producción de forma indefinida. Son un bisturí, no un martillo.

En manos de un DBA que sabe lo que hace, pueden ser la diferencia entre una operación arriesgada y un desastre. Pero mal usados, solo sirven para saturar discos, ralentizar el I/O y dar una falsa sensación de seguridad.

Así que la próxima vez que pienses en crear un snapshot, hazlo sabiendo por qué lo haces, cuánto tiempo lo vas a mantener, y qué coste estás dispuesto a asumir. Y cuando ya no lo necesites… bórralo. Que no eres un coleccionista.

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

Funciones inline en SQL Server.

Si vienes del artículo anterior sobre procedimientos almacenados vs funciones, ya sabes que no todas las funciones son iguales ni todas son igual de bienvenidas en producción. Hoy vamos a entrar en el terreno de las que sí merecen un sitio en entornos serios, las funciones inline con valores de tabla, o inline TVF.

Porque sí, en SQL Server también hay funciones que se comportan bien, no matan el rendimiento y hasta pueden ser aliadas del optimizador. Eso sí, como siempre en SQL Server, hay letra pequeña. Y no es precisamente corta.

¿Qué es exactamente una función inline?

Una función inline con valores de tabla es un objeto de base de datos que devuelve una tabla como resultado, definida a partir de una única instrucción SELECT. La sintaxis es clara: no hay BEGIN…END, no hay tablas variables intermedias ni lógica procedural. Solo una expresión SELECT que define el resultado.

Un ejemplo básico:

La clave aquí está en el hecho de que la función no tiene cuerpo procedural. El RETURN devuelve directamente el SELECT, sin necesidad de declarar una variable tipo tabla ni usar bloques de control. Y eso le encanta al optimizador de consultas.

¿Por qué son tan diferentes del resto?

La principal ventaja de las funciones inline es que se expanden dentro del plan de ejecución de la consulta que las llama. Es decir, se comportan como si hubieras escrito el SELECT directamente en la consulta. Esto permite al optimizador generar un único plan coherente, hacer estimaciones de cardinalidad más precisas y aplicar filtros, joins o incluso reescrituras sin perder información.

No hay saltos de contexto, no hay opacidad. Todo se ve. Todo se puede optimizar. Todo fluye.

Esto contrasta brutalmente con las funciones escalares o las funciones con valores de tabla multisentencia, donde el optimizador pierde visibilidad, rompe el plan y acaba tirando de valores fijos o estimaciones aleatorias dignas de una quiniela.

En resumen, si necesitas encapsular lógica reutilizable que devuelve datos en forma de tabla y quieres mantener el rendimiento, la inline TVF es tu opción.

Buenas prácticas: lo que conviene hacer

Usar funciones inline no solo es una cuestión de sintaxis correcta. También hay que saber cómo diseñarlas para que sean eficientes, reutilizables y mantenibles. Aquí van algunas prácticas que realmente marcan la diferencia:

Primero, mantén la lógica centrada en una única operación clara. Si necesitas múltiples pasos, joins complejos, condiciones opcionales o lógica condicional, es probable que estés forzando demasiado el diseño y que deberías estar en un procedimiento o en una vista indexada (si tienes valor para ello).

Segundo, evita usar funciones inline como simples extractores de columnas. Si solo encapsulas un SELECT de una tabla sin añadir valor, estás generando una capa innecesaria que complica los planes y aporta poco. Úsalas cuando encapsules lógica real: filtrados, joins relevantes, condiciones específicas.

Tercero, documenta los parámetros con claridad. SQL Server no impone muchas restricciones, pero el que venga detrás (que probablemente seas tú dentro de seis meses) agradecerá saber qué espera exactamente cada parámetro y cómo afecta al resultado.

Por último, cuidado con los TOP y los ORDER BY. En funciones inline, el ORDER BY solo es válido dentro de un TOP… pero eso no significa que respete el orden en la consulta final. El optimizador puede decidir hacer lo que le venga en gana si no hay ORDER BY explícito en la consulta externa. Que no te sorprenda.

Casos de uso donde brillan

Hay escenarios donde una función inline brilla con luz propia. Uno de los más frecuentes: filtros complejos reutilizables. Supón que tienes una lógica de negocio que define qué pedidos se consideran “activos”, basada en múltiples condiciones, fechas, flags y columnas calculadas. Puedes encapsular esa lógica en una función inline y usarla como si fuera una subconsulta parametrizada.

Otro caso clásico: reportes o dashboards parametrizados. Si usas Power BI o cualquier herramienta de reporting que genere consultas dinámicas, puedes exponer funciones inline como “vistas parametrizadas” que reducen la complejidad del modelo y mejoran el mantenimiento.

Y por supuesto, también son útiles en procesos ETL que necesitan aplicar filtros reutilizables en múltiples pasos sin replicar lógica por todas partes.

Lo que NO debes hacer (aunque la tentación sea fuerte)

El hecho de que las funciones inline se comporten tan bien no significa que sean inmunes al mal diseño. De hecho, hay errores recurrentes que siguen apareciendo incluso entre DBAs con experiencia.

Uno muy común es usar funciones inline con un JOIN interno a una tabla de millones de filas sin tener en cuenta filtros exteriores. Como la función se expande, esa tabla puede aparecer en cada ejecución de forma inesperada y generar planes desastrosos.

Otro clásico, parámetros mal definidos o con valores opcionales que no se gestionan bien. SQL Server no permite parámetros opcionales en funciones, así que muchos intentan simularlo con NULL y condiciones tipo (@Param IS NULL OR Columna = @Param). Esto degrada los planes de ejecución, impide la indexación eficaz y rompe la estimación de cardinalidad. Una joya.

Y uno más, pensar que por ser una función inline, siempre va a ir rápido. Si la lógica interna es compleja, hace joins mal indexados o usa filtros poco selectivos, el plan puede seguir siendo un desastre. El que se vea no significa que sea bueno.

Comparación real: subconsulta vs función inline

Para los escépticos, vamos con un ejemplo sencillo.

Subconsulta tradicional

Esto se puede convertir en una función inline así:

Y luego usarla así:

¿La diferencia? En un entorno donde se reutiliza la lógica o se combina con otras condiciones, encapsularla en una función inline puede mejorar la legibilidad y el mantenimiento. Y con OUTER APPLY, se comporta como una subconsulta correlacionada, pero con visibilidad total en el plan.

Eso sí, no uses CROSS APPLY si no estás 100% seguro de que todas las combinaciones producirán resultado. Te lo recordarás a las 3 de la mañana.

Conclusión

Las funciones inline son una de esas herramientas que, bien usadas, te hacen la vida más fácil y el código más limpio. Mal usadas, solo complican las cosas sin aportar rendimiento ni claridad. No son la solución a todo, pero en el conjunto correcto de circunstancias, pueden sustituir a vistas, subconsultas o incluso procedimientos ligeros con mucha más flexibilidad.

Y sobre todo, te permiten encapsular lógica sin pagar el peaje que sí tienen otras funciones. Como siempre en SQL Server, no es solo cuestión de saber que existen, sino de saber cuándo y cómo usarlas. Porque sí, hay funciones buenas. Solo hay que reconocerlas.

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

Sargabilidad: el arte de no cabrear al optimizador

En SQL Server hay conceptos que separan al junior entusiasta del profesional que ha pasado noches enteras mirando planes de ejecución con el ceño fruncido. La sargabilidad es uno de ellos. Es esa palabra fea que no encontrarás en la RAE, pero que puede hacer que tus consultas vuelen… o se arrastren como un SELECT * sin índice por una tabla de 500 millones de filas.

Si llevas tiempo escribiendo T-SQL y nunca te has parado a pensar en si tus consultas son sargables o no, probablemente estés dejando rendimiento encima de la mesa. Y si trabajas con datos en serio, sabes que eso es inaceptable.

Qué es la sargabilidad (de verdad)

Sargabilidad viene del acrónimo SARG: Search ARGument-able. Es decir, que el motor de base de datos puede usar un índice para resolver la consulta de forma eficiente, sin escanear toda la tabla como si no hubiera mañana.

En SQL Server, una consulta es sargable cuando el predicado (la condición del WHERE, JOIN, HAVING, etc.) puede aprovechar un índice para filtrar datos directamente, sin tener que procesar fila por fila. En otras palabras: si el optimizador ve que puede usar un índice de forma directa, lo hará. Si no, te prepara un bonito Index Scan o Table Scan con aroma a cuello de botella.

Un ejemplo básico:

  • Sargable
  • No sargable

La diferencia es simple pero letal. En el primer caso, SQL Server puede usar un índice sobre la columna Nombre. En el segundo, como le has puesto una función encima, el optimizador no puede buscar directamente. Tiene que aplicar la función a cada fila y luego comparar. Y claro, eso escala tan bien como un script que hace DELETE sin WHERE.

Las funciones son el enemigo (cuando no sabes usarlas)

El caso anterior ilustra la regla de oro de la sargabilidad: si transformas la columna del predicado, estás condenado a un escaneo. Las funciones como LEFT, SUBSTRING, CONVERT, DATEDIFF, COALESCE o incluso simples operadores matemáticos, rompen la posibilidad de usar índices si se aplican sobre la columna.

Veamos otro clásico:

Esto es tan común como ineficiente. Lo correcto sería:

Y sí, es más feo. Pero el plan de ejecución será infinitamente más feliz. Y tú también, cuando no tengas que explicar por qué la consulta tarda 30 segundos con un índice que, supuestamente, estaba para eso.

ISNULL y COALESCE: los rompeíndices silenciosos

Uno de esos consejos que se repite como mantra en el mundo SQL es: «no uses funciones en columnas si quieres mantener la sargabilidad». Y, como todo buen mantra, es útil… pero no siempre cierto.

Tomemos el caso de ISNULL() y COALESCE(). Ambos permiten sustituir valores nulos por un valor por defecto. A efectos prácticos:

Parecen lo mismo, ¿no? Pero el optimizador de SQL Server no los trata igual. En la demo real que estás viendo, con un índice sobre DisplayName, la diferencia es cristalina.

ISNULL(): sorprendentemente sargable

Cuando usas ISNULL(DisplayName, ») = ‘Juan’, SQL Server aplica un Index Seek sin despeinarse. No le molesta la función. ¿Por qué? Porque el motor puede predecir exactamente lo que hace ISNULL() en este contexto: evalúa la columna, y si es NULL, la reemplaza por ». Como el predicado sigue siendo evaluable con un valor constante, puede derivarlo internamente como un predicado OR:

Y esa es la clave. Porque si escribes ese predicado tú directamente, es igual de eficiente y, de paso, más claro:

Mismo Index Seek. Misma eficiencia. Pero sin necesidad de funciones.

COALESCE(): aquí sí se complica

Ahora bien, si usas COALESCE(DisplayName, ») = ‘Juan’, el plan cambia. SQL Server ya no puede garantizar que la expresión sea determinista y sencilla de evaluar. Más que nada porque podría haber más de dos argumentos o que el orden de evaluación tuviera implicaciones semánticas. El resultado: Index Scan.

Así que no, ISNULL() y COALESCE() no son intercambiables en el WHERE (importante esto) cuando te importa el rendimiento. En teoría devuelven lo mismo, en la práctica afectan al plan de ejecución de formas distintas.

El OR: ese sospechoso habitual

Otro rompe-sargabilidad por excelencia es el OR, que puede obligar a escanear incluso si una de las condiciones sí es sargable. Imagina esto:

A menos que tengas un índice compuesto que cubra ambas columnas, el optimizador suele rendirse y tirar de escaneo. 

Así que ya sabes, si usas con frecuencia este tipo de filtros con OR asegurate de tener un índice compuesto bien creado.

Las columnas calculadas como tabla de salvación

A veces no hay forma humana de evitar una función sobre la columna. En esos casos, una solución decente (aunque no milagrosa) puede ser usar columnas calculadas indexadas. Si sabes que todo el mundo va a seguir escribiendo:

Puedes añadir una columna calculada persistente:

Y ahora sí, el predicado puede ser sargable, porque la función ya se calculó y se indexó. No es magia negra, es simplemente darle al optimizador algo que pueda usar sin pensar.

El caso especial del LIKE

El LIKE también puede ser sargable o no, dependiendo del patrón. Esta es sargable:

Esta no:

Si el comodín está al principio, el índice no sirve. No puede buscar «desde» ningún valor. El patrón tiene que permitir una búsqueda por rango, como ‘Juan%’ o incluso ‘J%’. Todo lo demás se traduce en escaneo.

Aquí no hay mucha escapatoria salvo usar Full-Text Search si de verdad necesitas búsquedas internas. O pensar si realmente necesitas buscar así, que a veces el problema no es técnico sino de requisitos mal planteados.

Cuando CONVERT(DATE, datetime) sí es sargable (sí, lo has leído bien)

Aunque llevamos un buen rato diciendo, con razón, que aplicar funciones sobre columnas rompe la sargabilidad, hay una excepción curiosa (y bastante útil) que merece su propio rincón en este artículo: la conversión de un datetime a DATE usando CONVERT o CAST.

Mira este caso donde CreationDate es un campo DATETIME:

Lo lógico sería pensar: “acabo de meterle una función a la columna del WHERE, esto va directo a un Index Scan, ¿verdad?”. Pues no. SQL Server es capaz de usar un Index Seek, incluso con esa conversión.

¿Por qué? Porque el motor es más listo de lo que a veces creemos. Internamente, evalúa que convertir un datetime a date reduce la precisión pero no cambia la semántica de ordenación, y por tanto puede generar un predicado de rango equivalente: desde 2010-06-05 00:00:00.000 hasta justo antes del 2010-06-06. Si hay un índice sobre la columna CreationDate, lo usa. Sin mirar atrás.

Ahora bien: esto no lo convierte en buena práctica universal.

Porque si haces esto:

El motor no te va a perdonar. Ahí sí hay Index Scan, porque ya estás forzando una conversión de tipo y de formato, y encima con ambigüedad regional. No hay forma de hacer un seek con eso.

Así que, como en todo, hay que ser precisos: CONVERT(DATE, datetime) es una excepción válida a la regla general, y SQL Server lo optimiza sin necesidad de escanear. Pero eso no quiere decir que cualquier CONVERT o CAST sea seguro.

JOINs y sargabilidad: el otro lado del desastre

La sargabilidad no solo importa en los WHERE. También afecta a los JOIN. Si haces cosas como:

Estás rompiendo toda posibilidad de usar un índice sobre B.Codigo. La función LEFT en el lado derecho del JOIN es como ponerle una venda en los ojos al optimizador. Y luego esperar que encuentre el camino solo. Mejor no.

Reescribe la lógica o introduce columnas auxiliares si hace falta, pero no pongas funciones en las condiciones de unión. A menos que tu hobby sea revisar planes de ejecución a las tres de la mañana.

Cómo detectar consultas no sargables

El mejor chivato es el plan de ejecución. Si ves Index Scan o Table Scan donde debería haber un Seek, es que tienes un problema de sargabilidad. También puedes usar las estadísticas de ejecución o SET STATISTICS IO ON para ver si se están leyendo más páginas de las que tocan.

Además, en SQL Server 2019+ puedes usar Intelligent Query Processing que, en algunos casos, mitiga errores de diseño como este… pero no es una excusa para escribir mal. Es un parche, no una solución.

Y si quieres una ayuda más visual, herramientas como SQL Sentry Plan Explorer o el propio SSMS con su plan gráfico te permiten ver rápidamente si estás tirando índices a la basura.

Scan no siempre es sinónimo de error (aunque duela admitirlo)

Otro punto clave: un Index Scan no siempre es el villano. Sí, lo hemos demonizado durante años, pero como todo DBA que ha peleado con planes de ejecución sabe, hay ocasiones en las que el escaneo es simplemente lo más eficiente.

Por ejemplo, si tu predicado devuelve un porcentaje alto de filas (pongamos, más del 25-30% de la tabla), al optimizador le puede salir más a cuenta ir a buscar los datos de una vez que intentar ser selectivo con un Seek y acabar con mil Key Lookup de regalo.

Lo mismo pasa cuando el índice cubre poco y el motor tendría que hacer lookups constantes para recoger el resto de columnas. En ese caso, el coste de los seeks individuales más los lookups supera con creces el coste de un buen escaneo. El optimizador no es tonto: elige lo que más conviene a nivel global de coste estimado.

Y aquí viene lo peligroso: si tu consulta está perfectamente escrita y sargable, pero el plan muestra un Scan, no asumas automáticamente que está mal. Revisa el plan, el número de filas estimadas, y el acceso a columnas. Lo que queremos evitar son los scans necesarios por diseño deficiente, no los que el motor elige porque son lo más razonable.

Conclusión

La sargabilidad no es un capricho del optimizador ni un tema menor. Es la base sobre la que se construye el rendimiento de cualquier sistema OLTP que merezca la pena. Ignorarla es como ir a una entrevista con el pantalón del pijama: técnicamente puedes, pero no deberías.

Escribir consultas sargables exige disciplina, conocimiento y cierta humildad. Hay que dejar de pensar en lo que «funciona» y empezar a pensar en lo que escala. Y cuando la diferencia entre una consulta sargable y otra que no lo es se mide en millones de lecturas lógicas… no hay excusa.

Así que la próxima vez que te enfrentes a un WHERE, piensa como el optimizador. No le pongas trabas, no le escondas la columna tras una función, y no le pidas milagros con predicados imposibles. Dale lo que necesita. Y si aún así se queja, entonces sí: culpemos al cardinality estimator.

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

Canalizaciones por nombre (Named Pipes) en SQL Server

Durante años, las canalizaciones por nombre (Named Pipes) han sido uno de esos protocolos de red que viven en las sombras de TCP/IP. Están ahí, aparecen en las configuraciones del SQL Server Configuration Manager, y de vez en cuando algún alma valiente pregunta si debería activarlas “por si acaso”. Y no, por si acaso no es un argumento válido en administración de sistemas, y mucho menos en bases de datos. Vamos a analizar qué son exactamente, cómo funcionan y en qué escenarios podrían tener sentido… si es que alguno queda en 2025.

¿Qué demonios son las canalizaciones por nombre?

Antes de decidir si las activamos o las dejamos durmiendo el sueño de los justos, conviene entender qué son. Las canalizaciones con nombre son un mecanismo de comunicación interprocesos (IPC) heredado del glorioso mundo de Windows NT. Permiten que dos procesos, incluso en máquinas diferentes, se comuniquen a través de una ruta virtual. En SQL Server, representan uno de los protocolos disponibles para aceptar conexiones de cliente.

Mientras que TCP/IP utiliza direcciones IP y puertos, Named Pipes utiliza una sintaxis como \\.\pipe\sql\query, y en red sería algo tipo \\Servidor\pipe\sql\query. Esta vía de comunicación puede ser más rápida en entornos muy controlados y locales (léase: conexión directa entre un cliente y un servidor dentro de la misma LAN y sin cuellos de botella), pero en la práctica actual… hay que hilar muy fino para justificar su uso.

TCP/IP vs Canalizaciones por nombre: ¿por qué seguimos hablando de esto?

La realidad es que TCP/IP es el protocolo estándar y recomendado para conexiones SQL Server, tanto en producción como en desarrollo. Es más robusto, más flexible, y más preparado para escenarios reales con múltiples capas de red, firewalls, balanceadores, NATs y demás fauna moderna.

Entonces, ¿por qué SQL Server sigue ofreciendo Named Pipes como opción? Por compatibilidad. Porque aún hay sistemas legacy que las usan. Y porque a Microsoft le cuesta soltar lastre tanto como a cualquiera que aún mantiene SQL Server 2008 en alguna esquina de su datacenter “temporal”.

Hay entornos donde, por motivos históricos o arquitecturas muy específicas, se configuraron conexiones a SQL Server utilizando Named Pipes. En esos casos, sí, deshabilitarlas podría romper algo. Pero esa es la excepción, no la norma.

¿Cuándo tienen sentido las Named Pipes?

Vale, no todo es blanco o negro. Hay escenarios, pocos pero existentes, donde las canalizaciones por nombre pueden tener cierta ventaja:

  • Conexiones locales (cliente y servidor en la misma máquina): En algunos benchmarks internos de Microsoft (de hace más de una década nada menos), se observó que el rendimiento de Named Pipes en conexiones locales era ligeramente superior al de TCP/IP. Pero, francamente, si ese es tu cuello de botella, tienes problemas mayores.
  • Autenticación integrada en entornos Windows puros: Las canalizaciones por nombre pueden simplificar ciertos escenarios de autenticación integrada en entornos totalmente controlados por Active Directory. Pero otra vez: TCP/IP también lo hace sin problemas.
  • Entornos legacy que no quieres (o puedes) tocar: Si tienes una aplicación que explícitamente se conecta usando np: o configuraciones hardcoded de canalizaciones con nombre, y no puedes modificarla… entonces no queda otra que habilitarlas.
  • Solución de problemas puntuales: En algunos casos, cuando el acceso por TCP/IP falla misteriosamente (DNS, puertos bloqueados, fuegos en el CPD…), usar Named Pipes puede servir para diagnosticar si SQL Server sigue vivo y coleando.

Pero si tu escenario no cae en alguno de estos puntos, las Named Pipes sobran.

Cómo funcionan realmente las canalizaciones por nombre

Cuando habilitas Named Pipes en SQL Server, el motor escucha en una canalización concreta: \\.\pipe\sql\query por defecto. El cliente debe conectarse utilizando ese nombre. Lo que muchos no saben es que esto no solo requiere que el cliente conozca la sintaxis, sino también que la resolución de nombres esté bien configurada (en red), y que no haya firewalls bloqueando el tráfico correspondiente.

Además, en entornos remotos, el protocolo puede comportarse de forma bastante torpe: mayor latencia en la negociación, más complejidad en el tráfico de red, y más exposición a errores difíciles de diagnosticar. Si te suena a dolor de cabeza… es porque lo es.

¿Qué pasa si dejo las canalizaciones por nombre activadas “por si acaso”?

Esto es como dejar todas las ventanas de casa abiertas por si te olvidas las llaves. En teoría podría ayudarte, pero en la práctica te estás exponiendo innecesariamente. Habilitar las canalizaciones por nombre sin necesitarlas abre un vector de ataque innecesario (sí, también hablamos de superficie de ataque), complica el troubleshooting de conexiones, y puede provocar que clientes mal configurados intenten conectar usando este protocolo en lugar de TCP/IP.

Por si fuera poco, cuando están activadas, SQL Server puede priorizarlas en la cadena de protocolos, lo que lleva a situaciones surrealistas como que un cliente tarde más de la cuenta en conectarse porque está intentando usar Named Pipes antes que TCP/IP.

Lo peor de todo es que, en redes modernas, usar Named Pipes puede ralentizar la conexión en lugar de mejorarla. Así que eso de activarlas para “ganar velocidad” es un mito que ya deberíamos haber dejado atrás con el disquete.

¿Y si las necesito, cómo las activo (o desactivo)?

Si a pesar de todo necesitas activar Named Pipes, el proceso es sencillo, pero no inmediato. Desde SQL Server Configuration Manager, accede al protocolo correspondiente bajo SQL Server Network Configuration, y ahí puedes habilitarlas o deshabilitarlas. Necesitarás reiniciar el servicio SQL Server para que los cambios tengan efecto.

Además, si vas a usarlas, asegúrate de configurar también correctamente la cadena de conexión en el cliente, usando el prefijo np: para forzar que se utilicen Named Pipes.

Y, por supuesto, monitoriza. No asumas que todo va mejor solo porque te conectaste. Comprueba latencias, errores, y la experiencia real del usuario. Porque los milagros no vienen de las canalizaciones.

¿Qué protocolo prioriza SQL Server?

El orden de los protocolos es importante. SQL Server Native Client (o el driver OLE DB / ODBC que uses) sigue un orden al intentar conectar, salvo que lo fuerces. Ese orden se define también en SQL Server Configuration Manager, y puedes modificarlo.

Si dejas Named Pipes activado y en primer lugar, el cliente intentará primero por ahí antes de probar TCP/IP. Si Named Pipes no está disponible o hay problemas de red, el tiempo de espera puede incrementarse de forma absurda. ¿Te suenan esas conexiones que tardan 20 segundos solo en conectar? Pues eso.

Conclusión

Las canalizaciones por nombre son como el fax, aún existen, aún funcionan, y hay quien defiende que tienen utilidad. Pero en la mayoría de escenarios modernos con SQL Server, no hay ninguna razón técnica sólida para tenerlas activadas si no se están usando.

No aportan ventaja real frente a TCP/IP, complican el diagnóstico, abren superficie de ataque, y pueden ralentizar la conexión. Si tu entorno las requiere, adelante, pero hazlo con conocimiento de causa. Si no sabes para qué las necesitas, es que no las necesitas.

Apaga las Named Pipes, reinicia tu SQL Server y duerme tranquilo sabiendo que has reducido complejidad innecesaria.

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