¿Por qué los linked server rinden tan mal?

Por qué los linked server en SQL Server rinden tan mal, cómo funcionan realmente y qué alternativas tenemos cuando fallan.

Pocas tecnologías han generado tanto rechazo silencioso como los linked servers en SQL Server. Todos los hemos usado alguna vez. Algunos hasta han intentado montar arquitecturas enteras con ellos, como si fueran túneles mágicos entre bases de datos. Y al principio todo parece funcionar… hasta que dejas de hacer pruebas con tablas de 100 filas y llega la realidad con sus millones. Entonces empieza el verdadero drama.

Hoy vamos a entrar al barro y a entender por qué los linked servers rinden tan mal, qué está pasando por debajo y qué alternativas tenemos cuando necesitamos algo que se parezca a un acceso remoto entre instancias. Pero, antes de abrir el quirófano y diseccionar por qué rinden tan mal, conviene repasar qué son exactamente.

¿Qué es un linked server?

Un linked server es una funcionalidad de SQL Server que nos permite acceder a datos almacenados en otro origen, como si fuera parte de nuestra propia instancia. Ese origen puede ser otra instancia de SQL Server, una base de datos Oracle, un Excel, un archivo Access o cualquier cosa que tenga un proveedor OLE DB compatible. Básicamente, nos permite ejecutar consultas distribuidas, mezclando datos de aquí y de allá, sin necesidad de ETL ni procesos intermedios.

Desde el punto de vista del T-SQL, un linked server actúa como un alias remoto: podemos hacer SELECT o incluso INSERT, UPDATE y DELETE sobre objetos que realmente viven en otro servidor. Todo a través de una conexión que, en apariencia, es transparente. Y aquí está el engaño.

Porque aunque la sintaxis parezca sencilla y todo pinte bien en la teoría, por debajo SQL Server tiene que hacer auténticas acrobacias para que eso funcione. Y, como veremos, muchas veces no lo consigue sin romperse una pierna por el camino.

Linked Server o lo que parece una buena idea en realidad es una trampa

El concepto es tentador. Con un linked server podemos conectarnos desde una instancia de SQL Server a otra, e incluso a otros motores de base de datos, como si todo estuviera en la misma base. Basta con un SELECT * FROM [ServidorRemoto].[Base].[Esquema].[Tabla] y listo. Bonito, directo, sin middleware.

Claro, si obviamos que la consulta puede tardar más que una auditoría fiscal y que la mitad de las optimizaciones que teníamos en mente se van por el desagüe.

El optimizador no es adivino

Uno de los mayores problemas de rendimiento viene de cómo SQL Server construye el plan de ejecución cuando hay un linked server de por medio. El optimizador necesita estadísticas para tomar decisiones inteligentes, pero cuando apuntamos a un servidor remoto, las estadísticas simplemente no están ahí. SQL Server no sabe cuántas filas hay, ni cuán selectiva es una condición, ni si merece la pena hacer un join remoto o traerse toda la tabla localmente.

¿Y qué hace cuando no sabe? Apuesta. Y como buen jugador conservador, apuesta mal.

Acaba generando planes de ejecución mediocres, que podrían parecer aceptables en una tabla de juguete, pero que se vuelven un desastre cuando la tabla tiene un volumen real. ¿El resultado? Lecturas innecesarias, joins ejecutados en el servidor equivocado y un tráfico de red digno de una transferencia de backups.

Linked Server PUSH vs PULL

Otro elemento clave es cómo SQL Server decide si “empuja” partes de la consulta al servidor remoto (lo que se conoce como pushing de consultas) o si tira de los datos hacia el local (pulling). Idealmente, querríamos que SQL Server enviase una subconsulta bien formada al servidor remoto, para que allí se ejecute lo que tiene sentido y solo nos devuelva lo necesario. Algo así como el plegado de consultas de Power BI.

Pero no. Muchas veces SQL Server prefiere traerse toda la tabla (sí, toda) al servidor local, y luego aplicar filtros, joins o agregaciones. Porque eso de optimizar entre servidores diferentes le cuesta. Y mucho.

Si alguna vez has hecho un SELECT COUNT(*) contra un linked server y has notado que tarda minutos en devolver un número, ya sabes por qué: se está trayendo todas las filas. A pelo.

El drama del Linked Server Provider

Detrás de cada linked server hay un proveedor OLE DB. Y no todos son iguales. Algunos soportan operaciones remotas de forma más o menos decente. Otros se comportan como si los hubiera programado un becario en prácticas en 1998.

Por ejemplo, el proveedor nativo de SQL Server a SQL Server (SQLNCLI o MSOLEDBSQL) tiene ciertas optimizaciones, pero ni con esas nos salva del todo. Ahora bien, si conectamos a Oracle, MySQL o, que no tengáis que sufrirlo, Access, el comportamiento puede ser completamente errático. Y la culpa, en parte, es del proveedor.

Si el proveedor no soporta pasar consultas completas o no permite ciertas operaciones, SQL Server lo suple como puede: trayendo filas, aplicando funciones en local, y rezando para que la red no esté saturada.

Transacciones distribuidas: el infierno del Linked Server

Si a alguien se te ocurre la brillante idea de meter una transacción que toque un linked server, prepárate. Entramos en terreno de las transacciones distribuidas, y con ello en el mundo de MSDTC (Microsoft Distributed Transaction Coordinator), uno de los servicios más temperamentales de Windows.

¿Funciona? A veces. ¿Es rápido? Ni de lejos. ¿Es seguro? Mejor no responder. Configurar MSDTC entre servidores, sobre todo en entornos con firewalls o clusters, es un vía crucis. Y aunque consigas que funcione, el rendimiento se desploma por la sobrecarga que supone coordinar commit y rollback entre servidores.

JOINs remotos: lo peor que puedes hacer por un Linked Server

Uno de los errores más frecuentes (y más costosos) es hacer joins entre una tabla local y otra remota. En muchos casos, SQL Server se trae la tabla entera del servidor remoto al local y luego hace el join. Si la tabla remota tiene 10 millones de filas y solo necesitábamos 5, mala suerte. Ya es tarde.

El problema se agrava si el join es sobre columnas sin índices en el remoto, o si las condiciones están ocultas tras funciones (como CAST, CONVERT o UPPER). SQL Server no es capaz de generar una consulta remota eficiente y recurre al “me lo traigo todo y ya lo filtro aquí”. Un plan perfecto si tienes acciones del proveedor de ancho de banda.

¿Hay alguna solución?

Sí, pero no mágica. La primera es no usar linked servers para consultas complejas o de alto volumen. Son útiles para tareas administrativas, sincronizaciones puntuales o lecturas ligeras. Pero si necesitas integrar datos entre sistemas, mejor piensa en otras alternativas.

Replicación, ETL, servicios web o incluso bases de datos distribuidas con lógica de federación (sí, esas cosas raras de Azure SQL) pueden ser opciones más razonables. También puedes optar por staging: traer datos relevantes a una tabla temporal o staging local antes de hacer las operaciones serias.

Otra alternativa, cuando no hay más remedio, es escribir consultas distribuidas con OPENQUERY. Esto obliga a que la consulta se ejecute remotamente, evitando que SQL Server decida hacer el pull de datos. No es bonito, pero al menos sabes lo que estás haciendo.

Y, por supuesto, nunca, nunca asumas que lo que funcionó en desarrollo (con 1.000 filas) escalará igual en producción (con 100 millones). No con linked servers. No hoy. No nunca.

Conclusión

Los linked servers tienen su lugar, pero no es en el rendimiento. Son una herramienta más, no la solución universal. Cuando los usamos sin entender sus limitaciones, el castigo no tarda en llegar. Lo hemos visto demasiadas veces: servidores que colapsan, redes saturadas, y consultas que mueren de inanición esperando datos que jamás deberían haber salido del servidor remoto.

¿Se pueden usar? Claro. Pero como todo en SQL Server, con cabeza, y sabiendo que a veces es mejor copiar datos que pretendiendo unir mundos que no están hechos para unirse en tiempo real.

Porque sí, puedes hacer joins entre servidores remotos, pero también puedes correr descalzo por un campo de cactus y ninguna de las dos opciones es recomendable

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

Mi nombre es Roberto Carrancio y soy un DBA de SQL server con más de 10 años de experiencia en el sector. Soy el creador del blog soydba.es donde intento publicar varios artículos a la semana (de lunes a viernes que los fines de semana me gusta estar con mi gente y disfrutar de mi moto) Espero que disfrutes leyendo este blog tanto como yo disfruto escribiendo y que te sea de utilidad. Si tienes alguna sugerencia, pregunta o comentario, puedes dejarlo al final de cada entrada o enviarme un correo electrónico. Estaré encantado de leerte y responderte. ¡Gracias por tu visita! Mi principal interés es compartir mi conocimiento sobre bases de datos con todo el que quiera aprenderlo. Me parece un mundo tan apasionante como desconocido. Fuera de lo profesional me encanta la cocina, la moto y disfrutar de tomar una cervecita con amigos.

Deja una respuesta