Inteligencia Artificial

Búsqueda híbrida en SQL Server: Combinando FULLTEXT y Vectores

Llevamos años viendo aplicaciones que convierten la busqueda de textos en una trituradora de CPU. El usuario escribe tres palabras, la capa de aplicación las trocea como puede, el ORM genera una consulta digna de un informe forense y SQL Server acaba haciendo lo que siempre hace, intentar salvarnos de nuestras propias decisiones. A veces lo consigue. A veces no. Y cuando no lo consigue, alguien abre una incidencia diciendo que “la base de datos va lenta”, como si el motor hubiera decidido por iniciativa propia montar un festival de LIKE ‘%texto%’.

La búsqueda de texto completo ha sido durante mucho tiempo nuestra herramienta principal para resolver este tipo de problemas. Los índices full-text permiten buscar términos dentro de columnas extensas, ordenar por relevancia y evitar que cada búsqueda acabe en un escaneo indecente. Ya hablé de esto con más detalle en el artículo sobre índices de texto completo o full-text indexes, porque siguen siendo una herramienta muy válida cuando necesitamos precisión léxica.

Pero ahora tenemos otro actor en escena: la búsqueda vectorial. SQL Server 2025, Azure SQL Database y SQL Database en Fabric incorporan capacidades nativas para trabajar con vectores, calcular distancias y ejecutar búsquedas aproximadas de vecinos más cercanos mediante VECTOR_SEARCH. En SQL Server 2025 estas capacidades están en vista previa y requieren habilitar PREVIEW_FEATURES. Además, Microsoft documenta que la versión más reciente de los índices vectoriales está disponible actualmente en Azure SQL Database y SQL Database en Microsoft Fabric.

La tentación evidente consiste en pensar que la búsqueda vectorial sustituye al full-text. Es una conclusión cómoda y moderna, pero equivocada. Es muy de presentación ejecutiva, lo que debería hacernos sospechar inmediatamente. La realidad es bastante más interesante, full-text y vectores resuelven problemas distintos, y la búsqueda híbrida aparece precisamente cuando dejamos de tratarlos como enemigos.

Antes de lanzarnos a escribir T-SQL como si no hubiera mañana, conviene dejar claro el problema de fondo.

La búsqueda híbrida no es IA pegada con cinta americana

La búsqueda híbrida combina una búsqueda léxica tradicional con una búsqueda semántica vectorial y fusiona después ambos conjuntos de resultados mediante una técnica de reordenación. La idea parece sencilla, una rama encuentra coincidencias de palabras con full-text indexes, la otra encuentra documentos semánticamente cercanos mediante comparación de embeddings, y una fase final decide qué documentos merecen aparecer arriba.

La clave está en esa última frase. No basta con ejecutar dos consultas y hacer un UNION. Eso no es búsqueda híbrida. Tampoco basta con sumar una puntuación full-text y una distancia vectorial, porque ambas magnitudes viven en universos matemáticos diferentes. SQL Server no va a convertir una escala relativa de relevancia textual y una distancia de coseno en una verdad universal solo porque usemos alias bonitos.

El full-text devuelve señales de relevancia asociadas a coincidencias lingüísticas. CONTAINSTABLE y FREETEXTTABLE devuelven una columna RANK con valores ordinales entre 0 y 1000, pero esos valores indican orden relativo dentro del conjunto devuelto. Microsoft advierte que el valor real no debe tratarse como una puntuación absoluta y puede variar entre ejecuciones.

La búsqueda vectorial, en cambio, devuelve una distancia. Si usamos coseno, valores más bajos indican mayor cercanía cuando trabajamos con VECTOR_DISTANCE o con la columna distance generada por VECTOR_SEARCH. Esa distancia expresa proximidad geométrica entre embeddings, no coincidencia literal de términos. Comparar directamente ambas señales es como comparar páginas leídas con cuanto agua está lloviendo fuera. Puedes hacerlo, pero no significa nada útil.

Por eso la búsqueda híbrida necesita una fase de fusión por rango. No fusionamos puntuaciones brutas, fusionamos posiciones. Y ahí entra Reciprocal Rank Fusion, más conocido como RRF.

Para entender por qué esto importa tanto, primero hay que asumir que full-text sigue siendo necesario.

Full-text: precisión léxica, no comprensión semántica

Un índice full-text sigue siendo una pieza excelente cuando necesitamos encontrar términos, variantes lingüísticas, prefijos, expresiones ponderadas o documentos donde aparecen palabras concretas. No es una tecnología vieja por no llevar “AI” en el nombre. De hecho, suele ser mucho más útil que una demo de embeddings cuando el usuario busca un código, una referencia contractual, un identificador de error o una cláusula exacta.

Imaginemos una base de conocimiento de soporte. Si el usuario busca OOM-802, lo normal es que quiera documentos que contengan OOM-802. No quiere artículos “conceptualmente relacionados con problemas de memoria”. Quiere ese código. Exactamente ese. Si le devolvemos un documento sobre “optimización general de memoria en servidores de aplicaciones” porque está cerca en el espacio vectorial, hemos hecho una búsqueda muy sofisticada y muy inútil. Todo muy moderno, todo muy mal.

Búsqueda de texto completo

Aquí full-text brilla. CONTAINSTABLE permite buscar en una columna indexada y obtener una lista ordenada por relevancia. Además, podemos limitar el volumen con el parámetro top_n_by_rank, algo especialmente importante cuando la condición puede devolver decenas o cientos de miles de filas. La documentación de Microsoft indica que limitar resultados con top_n_by_rank puede mejorar drásticamente el rendimiento, porque SQL Server ordena las coincidencias por rango y devuelve solo las primeras.

Esto no significa que full-text entienda el significado. Si buscamos “vehículo económico”, no podemos asumir que devuelva “coche barato”. Puede haber cierta ayuda lingüística según idioma, tesauro y configuración, pero no estamos ante comprensión semántica general. Full-text trabaja con términos, proximidad, formas lingüísticas y ranking textual. Los embeddings trabajan con representación numérica del significado. Mezclarlos sin entender esta diferencia es una forma estupenda de construir una solución que falle justo cuando el usuario la necesite.

En artículos anteriores del blog ya traté los índices de texto completo desde la perspectiva del DBA. Esa base sigue siendo necesaria. La búsqueda híbrida no elimina el conocimiento de full-text, lo potencia. Si alguien quiere saltar directamente a vectores sin entender CONTAINS, FREETEXT, CONTAINSTABLE, catálogos full-text, stopwords y ranking, adelante. Pero luego no vale llorar.

La otra mitad del problema está en la búsqueda semántica.

Vectores: significado aproximado, no magia contractual

Un embedding representa un texto como un vector numérico. La idea práctica es que textos con significado parecido generen vectores cercanos. A partir de ahí, podemos medir distancias mediante coseno, producto escalar o distancia euclídea, y recuperar los documentos más cercanos al vector de consulta. SQL Server permite realizar búsquedas exactas con VECTOR_DISTANCE, calculando la distancia entre el vector de búsqueda y los vectores almacenados. Microsoft describe este enfoque exacto como un cálculo exhaustivo que garantiza recuperar los vecinos más cercanos, aunque puede resultar costoso en conjuntos grandes.

La búsqueda exacta tiene una ventaja fundamental, no aproxima. Calcula. Si filtramos primero por cliente, estado, idioma, producto o fecha, y después aplicamos VECTOR_DISTANCE sobre un conjunto pequeño, podemos obtener resultados muy buenos sin necesidad de crear un índice vectorial. Esta estrategia suele ser más sensata de lo que parece, sobre todo en tablas medianas o en escenarios donde los filtros relacionales reducen mucho el número de candidatos.

La búsqueda aproximada, por su parte, usa estructuras especializadas para evitar comparar contra todos los vectores. En SQL Server y Azure SQL hablamos de VECTOR_SEARCH, que busca vectores similares mediante un algoritmo aproximado de vecinos más cercanos. Con la versión más reciente de los índices vectoriales, la sintaxis recomendada usa SELECT TOP (N) WITH APPROXIMATE y deja atrás el antiguo parámetro TOP_N, que Microsoft marca como obsoleto para índices recientes.

Índices vectoriales: grafos de embeddings

Aquí aparece DiskANN. Un índice vectorial de tipo DiskANN acelera la recuperación aproximada navegando una estructura de grafo pensada para localizar vecinos cercanos sin recorrer todo el conjunto. Eso tiene un coste. Hay mantenimiento, requisitos, restricciones y decisiones de diseño. No creamos un índice vectorial porque la palabra “vector” aparezca en una reunión. Lo creamos cuando el volumen, la latencia esperada y el patrón de consulta lo justifican.

En el artículo sobre DiskANN y búsqueda vectorial en SQL Server 2025 ya expliqué por qué no conviene indexar vectores en cualquier tabla. Esta recomendación sigue siendo válida. Si tienes 3.000 filas y filtros buenos, probablemente VECTOR_DISTANCE con búsqueda exacta te dé una solución más simple, más predecible y más fácil de razonar. La complejidad innecesaria siempre encuentra la forma de facturarse más tarde.

Como véis, la búsqueda semántica resuelve muy bien consultas ambiguas. “Portátil ligero para viajar”, “incidencia parecida a error de memoria”, “cliente molesto por retrasos recurrentes” o “documentación sobre migración sin parada” son ejemplos donde la coincidencia literal se queda corta. Pero esa misma flexibilidad puede volverse peligrosa cuando la consulta contiene un literal crítico.

Por eso necesitamos una arquitectura híbrida.

El patrón correcto: recuperar candidatos y fusionar rangos

La búsqueda híbrida no debería ejecutar una búsqueda vectorial contra toda la tabla y otra full-text sin límite para después cruzar todo alegremente. Eso solo consumiría recursos a lo loco. El patrón correcto consiste en recuperar un número razonable de candidatos por cada rama y fusionar después esos candidatos mediante un ranking controlado.

La rama léxica puede usar CONTAINSTABLE o FREETEXTTABLE, según queramos una búsqueda más precisa o más lingüística. Para códigos, identificadores, términos técnicos y mensajes de error, normalmente prefiero CONTAINSTABLE. Para búsquedas más naturales o descriptivas, FREETEXTTABLE puede encajar mejor. No son intercambiables, aunque en muchas aplicaciones se usen como si lo fueran. Luego nos extraña que el buscador parezca tener resaca.

La rama semántica puede usar VECTOR_DISTANCE o VECTOR_SEARCH. Si queremos una búsqueda exacta sobre pocos candidatos, VECTOR_DISTANCE es una buena opción. Si tenemos cientos de miles o millones de embeddings, baja tolerancia a latencia y un índice vectorial adecuado, VECTOR_SEARCH pasa a tener sentido. Microsoft también documenta que los índices vectoriales recientes aplican predicados de WHERE durante el proceso de búsqueda vectorial mediante filtrado iterativo, no simplemente después de recuperar vecinos, pero eso, de momento solo está en Azure.

Unir resultados 

La fase final no debe sumar RANK full-text con distancia vectorial. Debe convertir cada lista en posiciones ordinales y aplicar RRF. La fórmula general es sencilla:

score(d) = Σ 1 / (k + rank_i(d))

Donde rank_i(d) es la posición del documento d en la lista i, y k es una constante de suavizado. Si un documento no aparece en una rama, esa rama aporta cero. No aporta un rango inventado de diez mil, salvo que queramos aplicar una penalización heurística deliberada. RRF canónico suma contribuciones de listas donde el documento existe, lo demás ya es cocina propia.

El valor k = 60 aparece a menudo como constante práctica. No es una ley divina, ni una recomendación que debamos tatuarnos pero si podríamos decir que es un estándar del mercado. Un k más bajo da más peso a las primeras posiciones; un k más alto suaviza la diferencia entre posiciones. En buscadores internos suelo empezar con 60, medir, revisar consultas reales y ajustar. Sí, medir. Esa costumbre extravagante que a veces evita reuniones.

Vamos a bajarlo a código.

Modelo de datos para un escenario realista

Supongamos una tabla de tickets de soporte. Cada ticket tiene una descripción textual, metadatos relacionales y un embedding generado a partir del contenido que queremos buscar. No voy a centrarme aquí en la generación del embedding porque ya traté las búsquedas semánticas con IA en SQL Server 2025 en otro artículo, y además dejé ejemplos prácticos en YouTube para quien quiera ver el flujo completo con más calma.

La tabla podría tener esta forma simplificada:

El índice relacional no es decorativo. En una arquitectura híbrida seria, los filtros siguen importando. Si buscamos tickets de un cliente concreto, de un producto concreto o de un rango temporal, no queremos que la parte vectorial se comporte como un turista perdido recorriendo toda la ciudad. Queremos acotar el problema antes de calcular distancias.

El índice full-text iría sobre las columnas textuales relevantes. En producción hay que cuidar idioma, catálogos, stoplists y fragmentación del índice full-text, pero el esqueleto sería este:

El LANGUAGE 3082 corresponde al español. En entornos multidioma, este detalle se complica bastante. Un catálogo global con textos mezclados en cinco idiomas y una sola configuración lingüística no es internacionalización; es una ruleta. Si el negocio necesita búsquedas multidioma, hay que diseñar para ello, no rezar para que el motor “lo entienda”.

Para la parte vectorial, un índice DiskANN puede crearse así cuando el volumen lo justifique:

Los índices vectoriales recientes exigen al menos 100 filas con vectores no nulos antes de poder crearse, requieren una clave primaria clustered y tienen limitaciones actuales como ausencia de particionado, restricciones con TRUNCATE TABLE, no replicarse a suscriptores y problemas de despliegue directo con DacPac o BACPAC porque el índice se crea antes de cargar datos.

Esto ya nos da una pista importante: no hablamos de un índice cualquiera. No es un IX_Tabla_Campo que añadimos a las tres de la tarde para callar una alerta. Un índice vectorial afecta al ciclo de vida de la tabla, al despliegue, al mantenimiento y a los procesos de carga. Si el plan de despliegue de tu base de datos ignora esto, no tienes un plan; tienes un problema.

Ahora sí, veamos una búsqueda híbrida exacta.

Búsqueda híbrida exacta con VECTOR_DISTANCE

El primer patrón usa VECTOR_DISTANCE. Es el más fácil de razonar porque calcula distancias reales contra los candidatos considerados. Conviene usarlo cuando el conjunto final no es enorme, cuando los filtros relacionales son selectivos o cuando la precisión importa más que la latencia extrema.

El siguiente ejemplo recibe una consulta textual, genera su embedding y combina la rama semántica con la rama full-text. Limitamos ambas ramas para no fusionar medio millón de filas, es la forma de decirle a SQL “no hagas barbaridades”.

Hay varias decisiones intencionadas aquí. La rama semántica no calcula distancia contra toda la tabla, sino contra CandidatosFiltrados. Esto permite que el optimizador use índices relacionales antes de aplicar la parte matemática. Si el cliente tiene 4.000 tickets abiertos del producto, calcular 4.000 distancias puede ser razonable. Si tiene 40 millones, probablemente estamos diseñando otra cosa.

La rama léxica usa CONTAINSTABLE con top_n_by_rank. Ese cuarto parámetro limita el número de resultados full-text devueltos. No quiero traer todos los tickets que contengan “memoria” para después descubrir que el usuario solo verá 20 filas. Esa es la diferencia entre una consulta y un castigo.

La fusión usa FULL OUTER JOIN porque un documento puede aparecer solo en la rama semántica o solo en la rama léxica. Después, COALESCE(1.0 / (@rrf_k + rango), 0.0) suma cero cuando el documento no aparece en una rama. Esto es importante, no inventamos rangos artificiales. Si queremos penalizar más o menos los resultados huérfanos, podemos hacerlo, pero entonces debemos reconocer que estamos introduciendo una heurística adicional.

También ordeno por criterios secundarios. En producción, los empates ocurren. Si no defines desempates, el motor puede devolverte órdenes distintos entre ejecuciones. Y cuando el usuario dice “ayer salía primero”, a nadie le divierte explicar que una ordenación parcial no garantiza estabilidad. Bueno, a nadie normal, que yo estoy aquí preparando el artículo más largo de todos los que he escrito para explicaros eso.

Este patrón exacto es muy útil cuando trabajamos con filtros fuertes. Pero si el volumen semántico es grande y necesitamos latencia baja, toca pasar a búsqueda aproximada.

Búsqueda híbrida aproximada con VECTOR_SEARCH

VECTOR_SEARCH representa el patrón de búsqueda vectorial aproximada. Con índices vectoriales recientes, la sintaxis exige SELECT TOP (N) WITH APPROXIMATE y ordenación ascendente por la columna distance, que es la única clave de ordenación válida para los resultados aproximados. Si existe un índice ANN compatible con la misma métrica y columna, puede usarse, si no existe, el motor puede recurrir a kNN y emitir una advertencia.

Una versión híbrida aproximada puede quedar así:

Este ejemplo es parecido al anterior, pero cambia la rama semántica. Ahora usamos VECTOR_SEARCH, que devuelve la columna distance. La consulta solicita explícitamente resultados aproximados con WITH APPROXIMATE. Esto no es un adorno sintáctico, en índices recientes, Microsoft separa claramente la búsqueda aproximada de la exacta mediante esta sintaxis.

La presencia del WHERE dentro de la rama semántica también importa. En versiones recientes de índices vectoriales, Microsoft documenta filtrado iterativo, es decir, los predicados se aplican durante el proceso de búsqueda vectorial, no únicamente después. En versiones antiguas, los filtros podían aplicarse solo después de recuperar vecinos, lo que provocaba resultados vacíos o incompletos si los primeros vecinos no cumplían el filtro. Esta diferencia no es teórica, afecta directamente a la calidad del resultado.

Si trabajas con índices vectoriales antiguos, conviene migrarlos. Microsoft indica que los índices creados con estructuras anteriores se mantienen en la versión actual, pero quedarán retirados en una versión futura, y para obtener las capacidades recientes hay que eliminar y recrear el índice. La propia DMV sys.vector_indexes, junto con sys.indexes y sys.tables, permite consultar la versión registrada en los parámetros de construcción.

Esto introduce una responsabilidad nueva para el DBA. Ya no basta con saber si el índice existe. Hay que saber qué versión tiene, qué sintaxis admite, cómo se comporta con filtros y si soporta mantenimiento DML completo. El “tenemos índice vectorial” se parece demasiado al “tenemos backup”: la frase tranquiliza hasta que preguntas cuándo se ha probado.

RRF con pesos: cuando no todas las señales valen lo mismo

RRF básico da el mismo peso a cada rama. Eso suele ser un buen punto de partida, porque evita discusiones prematuras. Pero no todos los dominios tienen la misma necesidad de precisión literal y contexto semántico. En una base de conocimiento técnica, los códigos de error, nombres de procedimiento, versiones y referencias internas suelen pesar mucho. En un catálogo de productos o una búsqueda documental abierta, la semántica puede tener más protagonismo.

Podemos introducir pesos sin romper la estructura:

Esto ya no es RRF puro, sino RRF ponderado. No hay problema, siempre que seamos conscientes de ello. Lo peligroso no es ajustar el algoritmo, lo peligroso es hacerlo sin medir. Si damos demasiado peso a la rama semántica, un literal crítico puede quedar enterrado bajo documentos conceptualmente parecidos. Si damos demasiado peso a la rama léxica, perdemos recall semántico y volvemos al mundo de “no encuentro coche barato porque el documento dice vehículo económico”.

En entornos serios conviene registrar consultas reales, resultados seleccionados, clics, aperturas, tiempo hasta resolver la incidencia y feedback explícito si existe. Después podemos comparar configuraciones de pesos, tamaños de candidatos y valores de k. La relevancia no se calibra en una pizarra. Se calibra con datos y pruebas. Qué concepto tan revolucionario.

También podemos modificar pesos en función de la consulta. Si detectamos patrones de códigos, identificadores, GUIDs, números de versión o referencias internas, podemos favorecer full-text. Si la consulta es larga, descriptiva y sin literales críticos, podemos favorecer semántica. Este tipo de adaptación suele dar mejores resultados que una configuración fija para todos los casos.

La detección no tiene por qué ser perfecta. Basta con aplicar reglas prudentes. Una consulta con OOM-802, SQLSTATE 40001, KB500 o Procedure dbo.X probablemente necesita más precisión léxica. Una consulta como “el agente se queda bloqueado después de actualizar y consume mucha memoria” puede beneficiarse más del vector. El usuario no nos entrega una intención formal; nos entrega una frase. Nuestro trabajo consiste en no destrozarla.

El tamaño de los candidatos importa más de lo que parece

Uno de los errores más comunes en búsqueda híbrida consiste en recuperar pocos candidatos por rama. Si pedimos top 10 semántico y top 10 léxico para devolver top 10 final, apenas damos margen al algoritmo de fusión. RRF necesita espacio para encontrar documentos que quizá no sean número uno en ninguna rama, pero sí sean buenos en ambas.

Un documento que aparece en posición 12 en la rama semántica y posición 8 en la rama léxica puede ser mucho mejor resultado global que otro que aparece en posición 1 semántica y no aparece en léxica. Si solo recuperamos diez candidatos por rama, el primero puede sobrevivir y el segundo puede ni siquiera existir en la fusión. El algoritmo no puede ordenar documentos que nunca le hemos dado.

Por eso suelo trabajar con una ventana de candidatos bastante mayor que el resultado final. Si voy a mostrar 20 resultados, empezar con 100 o 200 por rama suele ser razonable. Luego hay que medir. No es lo mismo una tabla de tickets internos que una base documental de millones de artículos. Tampoco es lo mismo una búsqueda con filtros por cliente que un buscador global público.

El parámetro top_n_by_rank de full-text ayuda en la rama léxica. En la rama vectorial aproximada, TOP (N) WITH APPROXIMATE marca la ventana semántica. En la rama exacta con VECTOR_DISTANCE, TOP (N) limita el cálculo ordenado final, aunque el coste previo depende de cuántas filas sobrevivan a los filtros relacionales.

Aquí conviene vigilar planes de ejecución, memoria concedida, spills, paralelismo y lecturas lógicas. También hay que observar la distribución de distancias. Si todos los documentos tienen distancias muy parecidas, la señal semántica quizá no discrimina bien. Si el full-text devuelve rankings muy planos, la parte léxica quizá necesita mejorar sintaxis, tesauro, stopwords o normalización de contenido.

La búsqueda híbrida no elimina el tuning. Le añade dimensiones nuevas. Por si alguien echaba de menos complicarse la vida.

Exact search frente a ANN: elegir sin postureo

La búsqueda exacta con VECTOR_DISTANCE calcula distancias y ordena. Es simple, precisa y fácil de auditar. Si el conjunto candidato es pequeño, suele ser una gran elección. También es buena para validación, pruebas de calidad y comparación contra la búsqueda aproximada. En escenarios donde la exactitud es crítica, tener un modo exacto ayuda a detectar pérdida de recall introducida por ANN.

La búsqueda aproximada con VECTOR_SEARCH sacrifica exactitud teórica por velocidad. No tiene nada de malo. Muchos sistemas de búsqueda funcionan así porque el usuario necesita respuestas rápidas y suficientemente buenas. El problema aparece cuando alguien vende “aproximado” como si significara “igual pero más rápido”. No. Significa aproximado. La palabra está ahí, generosamente visible.

Microsoft documenta que VECTOR_SEARCH utiliza búsqueda aproximada de vecinos más cercanos, y que con índices recientes el optimizador puede decidir entre usar DiskANN o búsqueda kNN según las características de la consulta. También indica que, si no hay un índice ANN compatible con la métrica y la columna, se genera una advertencia y se usa kNN.

Esto tiene implicaciones operativas. Si una consulta esperada como aproximada cae a kNN por no tener índice compatible, puede cambiar radicalmente su coste. Si alguien crea el índice con métrica DOT y la consulta usa cosine, no esperes milagros. El motor no va a inventar un índice compatible porque el ticket esté marcado como urgente.

La métrica debe estar alineada con el modelo de embeddings y con la normalización aplicada. En muchos modelos textuales se usa coseno, pero no conviene asumirlo por costumbre. Hay que revisar cómo se generaron los embeddings, si están normalizados y qué distancia recomienda el proveedor o el patrón de uso. El DBA no tiene por qué entrenar el modelo, pero sí debe entender qué está almacenando y cómo se consulta.

Además, el índice vectorial no sustituye los índices relacionales. Microsoft recomienda combinar índices vectoriales con índices tradicionales en columnas usadas por filtros, especialmente cuando el filtrado iterativo puede aprovechar predicados selectivos.

Dicho de otra forma, seguimos necesitando buenos índices B-Tree. La IA no ha derogado la selectividad. Qué disgusto para algunos.

DML, versiones de índice y falsas verdades que caducan

Durante las primeras versiones, una de las limitaciones más agresivas de los índices vectoriales era que las tablas quedaban de solo lectura después de crear el índice. Para permitir DML había que aceptar índices obsoletos mediante configuración, con el riesgo de resultados no actualizados. Esa limitación existió y era importante.

Pero no conviene escribir arquitectura en piedra cuando la tecnología está en vista previa y cambia deprisa. Microsoft documenta que los índices vectoriales creados con la versión más reciente eliminan esa restricción: soportan INSERT, UPDATE, DELETE y MERGE, con mantenimiento automático y en tiempo real del índice. Los cambios son visibles para las búsquedas vectoriales después del commit.

Esto no significa que podamos olvidarnos del mantenimiento. Para reemplazos masivos de datos, por ejemplo al regenerar embeddings con otro modelo, Microsoft recomienda considerar eliminar y recrear el índice después de la carga para mantener calidad de búsqueda predecible. La estructura del índice se construyó con una distribución vectorial determinada; si cambiamos casi todos los embeddings, no deberíamos sorprendernos de que la calidad se resienta.

También siguen existiendo restricciones actuales. No hay soporte de particionado para índices vectoriales, la tabla necesita clave primaria clustered, TRUNCATE TABLE no puede ejecutarse directamente sobre tablas con índice vectorial y los despliegues con DacPac o BACPAC requieren cuidado porque el índice necesita datos no nulos existentes al crearse.

Esto cambia bastante el diseño de procesos ETL. Si regeneramos embeddings en bloque, quizá convenga cargar en una tabla staging, validar dimensiones, controlar nulos, medir duplicados y después hacer intercambio lógico. Si trabajamos en Azure SQL o Fabric con índices recientes, no tenemos que congelar la tabla para cada operación DML normal, pero sí debemos diseñar cargas masivas con cabeza.

También hay que monitorizar. La documentación menciona sys.dm_db_vector_indexes para observar salud del índice y tareas de mantenimiento. En sistemas donde el embedding cambia con frecuencia, esa DMV deja de ser curiosidad y pasa a ser parte del cuadro de mando operativo.

La conclusión práctica es sencilla, no repitas limitaciones antiguas sin mirar versión, pero tampoco vendas los índices vectoriales como índices normales. Ambas posturas son malas. Una por anticuada; la otra por ingenua.

Calidad de datos: embeddings duplicados y basura semántica

La búsqueda vectorial amplifica la calidad del contenido. Si generas embeddings sobre textos pobres, duplicados, genéricos o mal normalizados, el índice devolverá resultados pobres, duplicados, genéricos o mal normalizados. No hay misterio. El embedding no convierte documentación basura en conocimiento. Solo la representa numéricamente con mucha dignidad matemática.

Microsoft recomienda evitar conjuntos con alta proporción de embeddings duplicados, porque perjudican la calidad de resultados, desplazan vecinos más útiles y consumen recursos sin aportar valor.

Esto se ve mucho en bases de conocimiento donde múltiples artículos empiezan con la misma plantilla corporativa. “Estimado usuario, este documento describe el procedimiento para resolver incidencias relacionadas con…” Si generamos embeddings sobre todo el texto sin ponderar ni limpiar, la plantilla común puede contaminar la similitud. Después nos preguntamos por qué todos los documentos parecen iguales. Quizá porque hemos metido el mismo ruido en todos. Sorpresón.

Hay que decidir qué texto se embebe. No siempre interesa usar todo el documento. A veces conviene usar título, resumen, etiquetas, producto, síntomas y causa raíz. En otros casos interesa trocear documentos largos en fragmentos y buscar sobre chunks, no sobre documentos completos. Si un artículo de diez páginas contiene una sección relevante en la página ocho, el embedding global puede diluirla.

También hay que versionar el modelo de embeddings. Si hoy generamos vectores con un modelo y mañana con otro, no debemos mezclar ambos alegremente en la misma columna sin saber qué estamos haciendo. Las distancias entre vectores generados por modelos distintos pueden dejar de tener sentido. Como mínimo, guardaría ModeloEmbedding, FechaEmbedding, HashContenido y estado de generación.

Un diseño más serio podría separar documento y fragmentos:

Este modelo permite buscar fragmentos, no solo documentos. Después podemos agregar resultados por DocumentoID, aplicar RRF sobre fragmentos y mostrar el documento con el fragmento más relevante. Es más trabajo, claro. También es más útil. La alternativa es devolver documentos enormes y confiar en que el usuario encuentre el párrafo bueno. Eso no es buscador; es externalizar el problema.

Reordenación por documento cuando trabajamos con fragmentos

Cuando buscamos sobre fragmentos, aparece un problema adicional. Un documento largo puede tener muchos fragmentos y, por tanto, muchas oportunidades de aparecer. Si no controlamos esto, los documentos extensos dominan el ranking simplemente porque tienen más boletos. Es el mismo vicio de siempre, confundir cantidad con relevancia.

Una estrategia razonable consiste en fusionar primero a nivel de fragmento y después colapsar por documento, quedándonos con la mejor puntuación o aplicando una agregación controlada. Por ejemplo:

Aquí MAX(PuntuacionRRF) evita que un documento se dispare solo por tener muchos fragmentos moderadamente relevantes. El contador de fragmentos coincidentes puede servir como desempate suave, pero no debería dominar la ordenación. Si queremos algo más sofisticado, podemos usar una combinación entre mejor fragmento, número de fragmentos relevantes y diversidad de secciones.

En sistemas RAG, este patrón es especialmente útil. El buscador no solo decide qué documento mostrar; decide qué fragmento alimentar al modelo generativo. Si metemos fragmentos malos en el contexto, el modelo responderá con seguridad y poca vergüenza. La seguridad sin fundamento ya la conocemos de algunas reuniones de arquitectura, pero no hace falta automatizarla.

También podemos añadir filtros de seguridad y visibilidad antes de la búsqueda. Si un usuario no tiene permiso sobre un documento, ese documento no debe aparecer ni por semántica ni por full-text. Esto parece obvio hasta que alguien implementa el filtro después de generar el contexto para el modelo. 

Seguridad, permisos y fuga semántica

La búsqueda híbrida no solo afecta al rendimiento. También afecta a la seguridad. Un embedding puede codificar información sensible del texto original. No es una copia literal, pero tampoco deberíamos tratarlo como un dato inocente. Si generamos embeddings de documentos confidenciales y permitimos búsquedas semánticas sin aplicar permisos correctamente, podemos filtrar conocimiento aunque no devolvamos el texto completo.

La seguridad debe aplicarse antes de formar candidatos o durante el proceso de búsqueda, no al final de manera cosmética. En VECTOR_SEARCH, con índices recientes y filtrado iterativo, los predicados pueden aplicarse durante la búsqueda vectorial. Eso ayuda, pero no sustituye un diseño de seguridad correcto.

En SQL Server podemos resolver parte del problema con predicados relacionales, Row-Level Security o filtros explícitos por tenant, organización, rol o ámbito documental. Lo importante es que la rama léxica y la rama semántica usen exactamente la misma lógica de visibilidad. Si full-text filtra por permisos y vector no, la fusión RRF puede devolver identificadores que la rama textual jamás habría permitido. Y entonces empieza el baile.

También hay que controlar quién puede generar embeddings. Si usamos AI_GENERATE_EMBEDDINGS, debemos revisar modelo, permisos, configuración del servicio y trazabilidad. Si los generamos fuera y los cargamos en SQL Server, debemos validar dimensiones, formato, modelo, nulos y correspondencia con el texto original. Un embedding desalineado con su documento es una mentira muy rápida de consultar.

En entornos multi-tenant, yo evitaría búsquedas vectoriales globales salvo que el aislamiento esté muy claro. Filtrar por tenant no es opcional. Y si el volumen por tenant permite búsqueda exacta con VECTOR_DISTANCE, quizá esa sea la opción más controlable. No todo problema necesita ANN global. A veces la arquitectura sencilla gana porque tiene menos formas de fallar.

La seguridad no debe aparecer como epígrafe al final del proyecto. Si el buscador ya está construido y alguien pregunta “¿cómo filtramos por permisos?”, lo más probable es que la respuesta correcta sea “reescribiendo más de lo que te gustaría”.

Observabilidad: medir relevancia y medir coste

Una búsqueda híbrida tiene dos planos de observabilidad. El primero es técnico: duración, lecturas, CPU, memoria, spills, número de candidatos por rama, uso de índice vectorial, uso de índice full-text, plan elegido, cardinalidades estimadas y reales. El segundo es funcional: consultas reales, documentos mostrados, documentos abiertos, posición del clic, reformulaciones y satisfacción del usuario.

Si solo medimos rendimiento, podemos construir un buscador rapidísimo que devuelve basura. Si solo medimos relevancia, podemos construir un buscador magnífico que tumba producción cada vez que se usa. Ninguna de las dos cosas debería darnos orgullo profesional.

A nivel técnico, conviene registrar para cada búsqueda el texto normalizado, tamaño de candidatos léxico, tamaño de candidatos semántico, top_final, valor de k, pesos aplicados, duración total y duración por rama si separamos ejecución. También podemos guardar si la consulta se trató como “literal crítica” o “semántica dominante”. Esta trazabilidad permite ajustar sin adivinar.

A nivel funcional, el dato más valioso suele ser qué resultado acaba usando el usuario. En soporte, podemos vincular búsqueda con ticket resuelto o artículo seleccionado. Si es documentación interna, podemos medir apertura y permanencia. En buscadores de catálogo, conversión o selección. La relevancia real no siempre coincide con nuestra intuición, especialmente cuando los usuarios escriben cosas que harían llorar a un parser.

También hay que comparar full-text puro, vector puro e híbrido. No para hacer una gráfica bonita, sino para demostrar que la complejidad añadida aporta valor. Si la híbrida no mejora precisión, recall o tiempo de resolución, quizá estamos decorando arquitectura. Y la decoración en producción suele ser cara.

Un enfoque serio consiste en crear un conjunto de consultas de evaluación con resultados esperados. No tiene que ser perfecto. Basta con consultas representativas, incluyendo códigos exactos, frases ambiguas, sinónimos, errores ortográficos, consultas largas y consultas absurdamente cortas. Sobre ese conjunto podemos probar distintos pesos, tamaños de ventana y valores de k.

Sin evaluación, la búsqueda híbrida se convierte en “a mí me parece que va mejor”. Esa frase ha causado más daño que algunos NOLOCK.

Casos donde no usaría búsqueda híbrida

No todo buscador necesita híbrida. Si el usuario busca exclusivamente códigos, referencias exactas, identificadores legales o claves de producto, full-text o incluso índices relacionales bien diseñados pueden bastar. Meter embeddings ahí puede añadir ruido. Una búsqueda de Factura 2024-000834 no necesita poesía semántica.

Tampoco usaría híbrida como primera respuesta a un problema de contenido mal estructurado. Si los documentos no tienen títulos decentes, categorías, producto, idioma, fecha, permisos o estado, la búsqueda híbrida no arreglará el desastre. Solo lo hará más caro. Primero se ordena el contenido; después se mejora la recuperación.

En tablas pequeñas, evitaría crear índices vectoriales salvo que exista una razón clara. Microsoft indica que VECTOR_SEARCH puede funcionar sin índice mediante escaneo brute-force, aunque el rendimiento se degrada con datasets grandes. Para desarrollo, pruebas y conjuntos pequeños, esto puede ser suficiente.

También sería prudente con cargas masivas frecuentes. Si regeneramos embeddings continuamente, cambiamos modelos a menudo o reemplazamos gran parte del dataset, el coste de mantenimiento y reconstrucción puede pesar más que la ventaja de ANN. En esos casos hay que diseñar ventanas de carga, staging, versiones de índice y validaciones. No conviene descubrirlo durante una migración nocturna con tres personas mirando una barra de progreso.

Por último, no usaría híbrida sin una estrategia de seguridad clara. La búsqueda semántica puede recuperar contenido inesperado porque no depende de palabras exactas. Eso es precisamente lo que la hace potente. También es lo que la hace peligrosa si los permisos se aplican tarde o mal.

El mejor buscador no es el que usa más tecnologías. Es el que devuelve lo correcto, rápido, dentro de permisos y con un coste operativo razonable. Parece una obviedad, pero hay arquitecturas enteras construidas para demostrar lo contrario.

Buenas prácticas para llevarlo a producción

La primera buena práctica es separar claramente recuperación y reordenación. La rama full-text recupera candidatos léxicos. La rama vectorial recupera candidatos semánticos. RRF fusiona posiciones. Si mezclamos estas fases sin orden, acabaremos con consultas imposibles de depurar.

La segunda es limitar candidatos por rama. Ni full-text ni vector deberían devolver volúmenes masivos si el resultado final tendrá 20 filas. top_n_by_rank en CONTAINSTABLE y TOP (N) WITH APPROXIMATE en VECTOR_SEARCH son herramientas básicas para controlar el tamaño del problema.

La tercera es conservar filtros relacionales fuertes. Cliente, tenant, producto, estado, idioma, fecha y permisos deben formar parte del diseño. No todo debe resolverse por similitud. A veces una igualdad bien indexada vale más que un grafo vectorial entero. No queda tan bien en una presentación, pero ejecuta mejor.

La cuarta es versionar embeddings. Guarda modelo, fecha, hash del texto y estado de generación. Si cambias el texto, regenera el vector. Cuando cambies el modelo, no mezcles vectores sin control. Si falla la generación, no insertes basura silenciosa. La base de datos recordará tu negligencia con una precisión admirable.

La quinta es medir calidad, no solo latencia. Registra consultas reales y resultados usados. Ajusta pesos y ventanas con datos. RRF funciona muy bien como punto de partida, pero cada dominio tiene sus rarezas. En soporte técnico, los literales pesan mucho. Si es búsqueda documental, la semántica puede dominar. En comercio, atributos estructurados y disponibilidad pueden importar más que ambas.

La sexta es revisar versión y comportamiento de los índices vectoriales. Los índices antiguos tienen limitaciones distintas a los recientes. La sintaxis con TOP_N queda obsoleta para índices nuevos, mientras que SELECT TOP (N) WITH APPROXIMATE es el patrón actual documentado para la búsqueda aproximada con índices recientes.

La séptima es preparar despliegues y mantenimiento. Si usas DacPac, BACPAC, replicación, particionado o cargas masivas, revisa restricciones antes de comprometer la arquitectura. Los índices vectoriales no son invisibles para la operación diaria. El DBA va a convivir con ellos, y conviene que no sea en régimen de sorpresa permanente.

Todo esto suena menos emocionante que “hemos metido IA en el buscador”. También es bastante más probable que funcione.

Conclusión

La búsqueda híbrida no sustituye al full-text ni convierte la búsqueda vectorial en una solución universal. Lo interesante aparece precisamente al combinar ambas señales con criterio, full-text aporta precisión léxica, los vectores aportan contexto semántico y RRF permite fusionar resultados sin mezclar puntuaciones incompatibles.

El diseño correcto no consiste en lanzar dos consultas y rezar. Hay que limitar candidatos, aplicar filtros relacionales, elegir entre búsqueda exacta y aproximada, revisar versiones de índice, controlar permisos, medir relevancia y entender el coste operativo. La parte bonita de la demo dura diez minutos. La parte seria vive dia a dia en producción.

SQL Server está incorporando capacidades muy potentes para búsqueda semántica e híbrida, pero potencia no significa simplicidad. Un índice vectorial mal usado, una rama full-text sin límite o una fusión de puntuaciones mal planteada pueden convertir una gran idea en otra incidencia con prioridad alta.

La búsqueda híbrida merece sitio en arquitecturas modernas, especialmente en bases de conocimiento, soporte, documentación interna y sistemas RAG. Pero exige DBAs que entiendan el motor, no operadores que copien sintaxis de una demo. Como casi siempre, la diferencia entre una solución elegante y una chapuza cara está en los detalles. Y los detalles, por suerte o por desgracia, siguen sin indexarse solos.

 

Publicado por Roberto Carrancio en Cloud, SQL Server, 0 comentarios
GitHub Copilot con SQL Server: el choque entre SSMS y VS Code

GitHub Copilot con SQL Server: el choque entre SSMS y VS Code

El pasado mes de marzo, con la SQLCon 2026 de Atlanta, vimos varias novedades alrededor de GitHub Copilot para quienes trabajamos con SQL Server. Microsoft aprovechó el evento para reforzar dos frentes que, desde fuera, parecen muy parecidos: SSMS 22, ya con Copilot en disponibilidad general, y la extensión MSSQL de VS Code, que sigue creciendo con diseñador de esquemas, agent mode y otras superficies más cercanas al flujo de desarrollo. La mayoría de titulares se quedaron en la parte fácil, esa de “Copilot llega a todas partes”. Lo interesante empieza cuando uno rasca un poco y descubre que no, que no está llegando igual a todas partes, ni con la misma idea detrás.

En este artículo quiero centrarme en dos mecanismos concretos, porque ahí está la diferencia de verdad: las instrucciones personalizadas y las skills. Son dos formas distintas de decirle a Copilot cómo queremos que piense, qué contexto debe respetar y hasta dónde puede dejar de improvisar. Que ya sabemos que improvisar es una habilidad preciosa en jazz, pero en bases de datos suele costar bastante más.

Antes de entrar en el detalle, conviene empezar por lo que debería ser la base de cualquier uso serio de Copilot con SQL Server: las instrucciones.

Instrucciones personalizadas: donde de verdad empieza el contexto

Cuando hablo de instrucciones personalizadas no me refiero a un prompt largo y dramático que uno pega en el chat cada lunes. Me refiero a contexto persistente, reutilizable y con cierta autoridad. En VS Code, la documentación de Copilot lo plantea como un mecanismo para definir reglas comunes en archivos Markdown y hacer que se apliquen automáticamente a las peticiones de chat del workspace o del repositorio. En SSMS existe también ese modelo clásico de instrucciones de usuario y de repositorio, con copilot-instructions.md a nivel personal y .github/copilot-instructions.md a nivel de repositorio. Hasta aquí, ambos mundos hablan un idioma bastante parecido.

Un ejemplo simple de ese tipo de fichero sería algo así:

Este tipo de instrucciones funciona muy bien para marcar estilo, guardarraíles y convenciones. En otras palabras, sirve para decirle a Copilot cómo queremos que se comporte. Y eso ya ayuda bastante, sobre todo en equipos donde todavía hay quien cree que una tabla llamada Tbl_Clientes2_Final transmite serenidad arquitectónica. En VS Code, además, estas instrucciones pueden generarse con /init o /create-instructions, se aplican automáticamente al chat y tienen una prioridad definida entre nivel personal, repositorio y organización.

Instrucciones personalizadas adaptadas a SQL Server

Ahora bien, SSMS añade una capa bastante más interesante, y aquí es donde esto deja de ser genérico. Además de las instrucciones de usuario y repositorio, SSMS incorpora database instructions, que viven dentro de la propia base de datos como metadatos basados en propiedades extendidas y que aplican para todo el que consulte la base de datos con SSMS. Microsoft documenta dos nombres concretos: CONSTITUTION.md, para reglas globales de la base, y AGENTS.md, para contexto específico de objetos. No estamos hablando ya de “me gusta que indentes así”. Estamos hablando de “esta base funciona así, estas reglas de negocio no son negociables y esta tabla significa esto, aunque por su nombre nadie lo diría”.

CONSTITUTION.md es, en la práctica, una constitución de base de datos. Sirve para fijar normas generales y semánticas que deben aplicarse a cualquier interacción de Copilot con esa base. Un ejemplo razonable podría ser este:

Ese fichero no mejora el estilo. Mejora el entendimiento. Y esa diferencia es crucial. Cuando Copilot genera T-SQL sin contexto semántico, lo único que hace es adivinar con bastante seguridad en sí mismo. Cuando trabaja con una constitución pegada a la base, al menos tiene una oportunidad real de no inventarse la lógica del negocio sobre la marcha. Que parece una exigencia modesta, pero viendo algunas demos de IA últimamente casi suena revolucionaria.

AGENTS.md, por su parte, baja un nivel más y se aplica a objetos concretos. Ahí es donde tiene sentido documentar lo que jamás se deduce mirando nombres de columnas. Por ejemplo:

Este ejemplo es simple, pero deja ver lo importante: en SSMS el contexto puede residir dentro del dato y no solo alrededor del dato. Para mí, esa es la mejor idea que ha aparecido en esta historia. No porque sea vistosa, sino precisamente porque no lo es. Es una solución pensada por alguien que ha entendido que en SQL Server el problema rara vez es escribir una consulta; el problema es saber qué consulta tiene sentido escribir.

Una vez aclarado esto, toca la segunda pieza del artículo. Porque si las instrucciones sirven para fijar normas, las skills juegan una partida distinta.

Skills: capacidad reutilizable, no autoridad semántica

Las skills, tal como las documenta VS Code, no son instrucciones generales, sino capacidades especializadas. Hay que decir que las Skills no son exclusivas de Copilot, son un estandar de la industria presente en la mayoría de IAs generativas comerciales (Claude, OpenAI, Gemini o Github Copilot, por ejemplo). Sin embargo, a fecha de redaccion de este artículo, en SSMS no las tenemos disponibles. 

Sobre su uso, la propia documentación de Agent Skills las contrapone a las custom instructions de forma bastante clara: las instrucciones sirven para definir estándares y guías; las skills sirven para enseñar flujos, incluir scripts, ejemplos y recursos, y cargarse bajo demanda cuando el agente las considera relevantes. También son portables entre VS Code, Copilot CLI y otros entornos compatibles, mientras que las custom instructions son más específicas del ecosistema de VS Code y GitHub.

Dicho sin envoltorio comercial, una instrucción le dice a Copilot “compórtate así”; una skill le dice “cuando toque esto, trabaja de esta manera”. Es una diferencia importante, porque mucha gente intenta usar las skills como si fueran una constitución universal y luego se lleva la sorpresa correspondiente. No están pensadas para eso. Están pensadas para encapsular un procedimiento. La herramienta es buena. El malentendido también.

Un ejemplo sencillo de skill para SQL podría ser este:

Esto tiene bastante sentido en VS Code. Puede servir para reforzar disciplina antes de tocar esquema, para revisar convenciones o para encadenar pequeñas validaciones. Incluso puede ser muy útil en un equipo de desarrollo que trabaja con SQL y .NET en el mismo workspace. Pero conviene no pedirle a una skill lo que no promete. Una skill no reemplaza una constitución de base de datos, porque no vive en la base ni tiene ese nivel de anclaje semántico. Puede ayudar a leer instrucciones, empujar un flujo y mejorar bastante el resultado. Lo que no hace es convertir el contexto del repositorio en contexto nativo del dato.

Además, la propia documentación es bastante explícita con el alcance: las custom instructions se aplican siempre o por patrón; las skills se cargan para tareas específicas y bajo demanda. Esa diferencia basta para entender por qué una skill no es el sitio correcto para definir autoridad continua. Sirve para procedimiento. No sirve como sustituto serio de una política persistente. Y eso, en entornos con varias bases, varios dominios y objetos sensibles, importa bastante más de lo que algunos quieren admitir.

Llegados aquí, la pregunta lógica sale sola. Si las instrucciones personalizadas son tan útiles y las skills aportan tanto en VS Code, ¿por qué no tenemos exactamente lo mismo en ambos sitios?

¿Por qué no están en ambos sitios?

Como acabamos de ver en SSMS tenemos las database instructions y en VS Code las Skills pero no al revés. ¿Por qué?

La respuesta corta es que SSMS y VS Code no están diseñados para obedecer al mismo centro de gravedad y por tanto llevan caminos de desarrollo distintos. SSMS parte de la conexión activa, del esquema y de la base de datos como lugar natural del contexto. La documentación de Copilot en SSMS insiste precisamente en esa idea, entiende la conexión, el esquema y el trabajo que estamos haciendo sobre la base. Por eso tiene sentido que Microsoft haya añadido database instructions y que las haya apoyado en metadatos dentro de SQL Server. Si el centro es la base, el contexto tiene que poder vivir ahí.

VS Code, en cambio, está pensado para algo más amplio. La documentación de la extensión MSSQL lo describe como una experiencia para desarrolladores modernos, arquitectos, ingenieros de base de datos y escenarios donde SQL convive con ORM, APIs, generación de código, query builder, schema designer y agent mode. Incluso el diseñador de esquemas con Copilot abre una sesión de chat “scoped to the current schema context”, con cambios reflejados en diagrama, T-SQL y diff. Todo eso encaja muy bien con un entorno cuyo centro no es la base aislada, sino el proyecto completo.

Y aquí aparece la diferencia que, a mi juicio, merece un palito para las cabezas pensantes de Redmon. Si un desarrollador usa VS Code para todo, desde SQL hasta .NET, puede centralizar reglas del equipo en el repositorio y montar skills para reforzar flujos. Muy bien. Pero no puede apoyarse en un mecanismo nativo equivalente al de SSMS para adaptar contexto por base de datos o por tabla desde dentro del propio SQL Server. Tiene que definirlo todo en el mismo sitio o trocearlo artificialmente por carpetas, workspaces y archivos. Funciona, sí. Pero obliga a administrar el conocimiento desde fuera de donde ese conocimiento realmente vive. Y eso, en bases de datos con semánticas distintas, no es una limitación teórica. Es una limitación bastante práctica.

En otras palabras, SSMS ha resuelto mejor la pregunta “¿dónde debería vivir el contexto de una base de datos?”. VS Code ha resuelto mejor la pregunta “¿cómo integro Copilot en un flujo de desarrollo más amplio?”. Las dos respuestas tienen sentido. Lo que no tiene sentido es fingir que son intercambiables. Porque no lo son. Y cuando uno intenta usarlas como si lo fueran, acaba pidiéndole a una skill que haga de constitución o a un fichero de repositorio que actúe como conocimiento de tabla. 

Ya con esto, la conclusión debería ser simple. Y como el tema da para pedir más de lo que hay hoy, la cierro con una pequeña lista de deseos.

Conclusión: lo que me gustaría ver a continuación

Mi sensación a día de hoy es bastante clara. Las instrucciones personalizadas de base de datos son el mecanismo correcto para fijar normas persistentes. Las skills son el mecanismo correcto para empaquetar capacidades y flujos reutilizables. El problema no está en ninguna de las dos ideas. El problema está en que cada producto ha desarrollado solo la mitad que más le convenía. SSMS ha entendido muy bien el valor del contexto dentro de la base, pero no ofrece el ecosistema de capacidades componibles que sí vemos en VS Code. VS Code, por su parte, tiene una historia mucho más rica en skills, agentes y superficies de desarrollo, pero sigue sin bajar el contexto al nivel de la base y del objeto con la naturalidad que sí ofrece SSMS.

Mi primera petición sería bastante obvia: que VS Code pudiera consumir de forma nativa una constitución y agentes definidos dentro de SQL Server, no solo desde el repositorio. La segunda, que el diseñador de esquemas respetara desde el primer minuto ese contexto y no solo el esquema cargado. La tercera, que SSMS heredara una idea de skills más seria para procedimientos repetibles y no se quedara únicamente en la parte de instrucciones. Y la cuarta, quizá la más importante, que Microsoft dejara de presentar todo esto como si fuera el mismo Copilot en dos ventanas distintas, porque no lo es y ya va siendo hora de dejar de tratar a los usuarios técnicos como si no supieran distinguir entre contexto, estilo y gobierno.

Mientras eso llega, yo lo resumiría así: si quiero que Copilot respete mejor el dato, hoy miro a SSMS; si quiero que Copilot me acompañe mejor en el proyecto, hoy miro a VS Code. Y entre una cosa y otra, lo que seguimos necesitando es exactamente lo mismo que antes de la IA: contexto bueno, reglas claras y menos fe ciega en herramientas que todavía confunden velocidad con criterio.

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

Publicado por Roberto Carrancio en Otros, SQL Server, 0 comentarios

Búsquedas semánticas con IA en SQL Server 2025

En algún momento entre pelear con índices zombis y migraciones eternas, Microsoft ha decidido que SQL Server también podía ser inteligente. Y no me refiero al tipo de inteligencia que esperas de un MERGE bien hecho (que ya sabemos que es difícil de ver), sino a IA de verdad: modelos de lenguaje, embeddings, vectores y búsquedas semánticas integradas directamente en el motor. Sí, en nuestro motor de base de datos favorito.

En este artículo vamos a desmenuzar la nueva funcionalidad de SQL Server 2025 que permite integrar modelos de IA para realizar búsquedas semánticas directamente desde SQL. Sin inventos raros y, lo más sorprendente, sin tener que abandonar nuestro entorno habitual. Ahora podemos chatear con nuestros datos sin salir del Management Studio.

Inteligencia artificial en SQL Server: la cosa se pone serIA

(Perdón por el chiste. Es malísimo, lo sé)

Esto no es un plugin experimental ni una feature de análisis de datos metida con calzador. Microsoft ha incorporado capacidades de IA directamente en el motor de SQL Server. Y eso significa que podemos invocar modelos de lenguaje desde procedimientos almacenados, generar embeddings, indexarlos y hacer comparaciones semánticas en caliente.

Y todo sin que los datos salgan del servidor. La seguridad y el rendimiento siguen siendo prioridad: lo que hacemos es pasar una consulta a un modelo que genera un vector (el embedding) y lo compara con los vectores previamente almacenados localmente. Resultado: respuestas rápidas, semánticamente relevantes y sin montar un chiringuito en Azure (solo unos pocos clicks).

Vectores, embeddings y cosenos: la IA no entiende palabras, entiende números

Esto tiene que quedar claro desde el principio, la IA no trabaja con texto. Aunque lo parezca, la IA no sabe leer. Internamente trabaja con vectores, que son representaciones matemáticas de conceptos. Un vector es simplemente una lista ordenada de números (normalmente de 1536 dimensiones) que representa el “significado” de algo.

Cuando decimos “bicicleta para descenso de montaña”, un modelo de lenguaje genera un vector que encapsula ese significado. Ese vector es un embedding. Y lo interesante es que podemos comparar ese embedding con otros ya almacenados, usando la similitud de coseno, para encontrar los conceptos más cercanos.

Cuanto más cercano es el ángulo entre dos vectores, más parecido es su significado. No hay magia. Hay trigonometría. Pero no te preocupes, que no vas a tener que calcularlo tú: eso se lo dejamos al motor, que para eso está.

¿Cómo implementar esta IA?

En mis pruebas he usado AdventureWorks, cómo no. Desde la tabla de productos, extraemos las descripciones y, a esas descripciones, les generamos embeddings usando un procedimiento almacenado que recibe un texto y lo envía al modelo modelo en Azure OpenAI (podría ser otro, incluso en local, pero aquí opte por ir a lo fácil y rápido). Importante guardar estos embeddings en una tabla separada: más limpio y mejor rendimiento.

Por último, creamos un segundo procedimiento almacenado que recibe una frase, genera su embedding con el SP anterior y, una vez obtiene su embedding lo compara con los embeddings almacenados en base para devolver los más cercanos. Y sí, todo desde SQL. Llamadas REST mediante, pero dentro de una SP.

Así obtenemos resultados en milisegundos. Eso es lo que tarda en calcular el embedding de una petición y compararlo con los datos. Rápido, elegante, sin ETLs de por medio y sin mover los datos de casa (siempre que uses un modelo local, claro).

¿Qué es esto de las búsquedas semánticas? La magia de la IA en SQL

Este es el verdadero factor diferenciador. No estamos hablando de una búsqueda con like ni de índices de texto completo (Full Text Indexes). Los embedding representan el significado de las palabras de manera que aspectos como sinónimos o incluso, el idioma de la búsqueda dejan de ser un impedimento.

En mis pruebas las descripciones de producto están en inglés, francés o incluso en chino. Yo he probado con prompts en español, inglés e incluso con redacciones ambiguas. El modelo entiende el significado, no la forma. Así que da igual si pides “bicicleta de descenso” o “bike for downhill mountain racing”: el embedding será muy similar y los resultados coherentes.

Una vez que te acostumbras, el LIKE te empieza a parecer una piedra tallada con cincel.

Aplicaciones reales más allá del hype

Vale, comparar descripciones de productos es “la demo fácil”. Pero no significa que no tenga valor ni que esto no se pueda llevar mucho más allá.

Gracias a esta funcionalidad puedes recomendar artículos relacionados en tu tienda web. Pero no es el único caso de uso. 

¿Tienes transcripciones de llamadas de soporte técnico? Embeddings. ¿Tienes feedback de clientes en la web? Embeddings. ¿Quieres analizar opiniones para saber si tu producto gusta o no? Más embeddings. Puedes clasificar sentimientos, detectar patrones de insatisfacción, anticipar problemas o simplemente automatizar búsquedas que hasta ahora eran imposibles sin intervención humana.

Y todo desde SQL Server. Sin montar pipelines, sin exportar a otro sistema, sin líos innecesarios. Aquí, en casa. Y eso, para un DBA con años de cicatrices, es música celestial pero también asusta. ¿Cómo va a impactar esto en nuestros sistemas? Solo el tiempo y el uso en cada escenario lo dirá.

Comparaciones por dentro: un vistazo rápido al cálculo de la IA

[Modo TryHard Activado] Por si tienes curiosidad matemática (o simplemente quieres saber si todo esto tiene sentido), el cálculo de similitud se basa en cosenos. Lo que estamos haciendo es comparar dos vectores, en nuestro caso el del prompt y el del producto. Para eso lo que se hace es calcular su producto escalar, sus magnitudes, y aplicar la fórmula del coseno.

Similitud = cos(θ) = (A·B) / (||A|| * ||B||)

Y la distancia, por si necesitas algo más crudo, es simplemente 1 – similitud. Cuanto más cercana a cero, más similares. Cuanto más cerca de uno, más distintos.

¿Y qué hacemos con eso? Ordenamos por similitud y nos quedamos con los más relevantes. No hay magia negra. Es álgebra lineal.

Conclusión

Esto no es hype. No es una demo para sorprender en eventos. Es una funcionalidad real, integrada, segura y rapidísima que cambia la forma en la que interactuamos con los datos.

SQL Server 2025 ha dejado de ser solo un motor relacional. Ahora también es un intérprete semántico. Y eso abre puertas que antes ni sabíamos que existían.

Lo dicho: si pensabas que lo habías visto todo en SQL, ya puedes ir quitándote esa idea de la cabeza. Y si no empiezas a trastear con embeddings, búsquedas semánticas y llamadas a modelos de lenguaje… no digas luego que no te avisamos.

Esto ha venido para quedarse. Y aquí, como siempre, trataré de analizarlo en condiciones.

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

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

DBA vs IA: Fight! La prueba de si la IA te va a quitar el trabajo

Los avances en inteligencia artificial son imparables, eso está claro. Además está claro que son la tendencia en el mercado, parece que términos como big data, cloud o blockchain son cosa del pasado y ahora lo moderno es tener IA hasta en el inodoro. Todas las empresas compiten por añadir IA a sus productos a la par que apuestan por integrar asistentes como ChatGPT o Copilot a sus procesos para facilitar la vida de los trabajadores. Y ojo que a mi me parece muy bien el avance de la IA pero no debemos olvidarnos de nuestra propia inteligencia natural. Por lo menos hasta que esto avance un poco más y vivamos en un mundo donde trabajen robots con IA y nosotros podamos dedicarnos a la holganza más absoluta. No me enrollo más, que lo que os vengo a contar hoy es muy interesante, una prueba más de cómo está ahora la IA en el ámbito de la administración de base de datos. Que cada uno saque sus conclusiones de si puede o no abandonarse a la vida contemplativa gracias a que una máquina complete sus tareas.

Definiendo la prueba 

Os pongo en situación, me encontraba yo desempeñando mis labores diarias, por las que me pagan no estas tareas del blog que lo hago por amor al arte. En ese momento estaba empezando a tomar el control de una nueva instancia de SQL, en concreto una instancia administrada en Azure. Se trata de una instancia compartida por varios microservicios donde cada uno de ellos tiene su base de datos, en principio, totalmente independiente a las demás. Por lo que he podido ver en el resumen de consumo de recursos del portal web de Azure, el uso de CPU es elevado en esta instancia y, por desgracia, ahí se queda todo lo que puedes ver en esta ventana. Igual que cuando miras el activity monitor de un SQL en local la verdad.

Como es un servidor compartido y hay varias bases de datos debo priorizar por lo que lo lógico es empezar por la que mayor consumo hace de los recursos. Partimos de una gran ventaja, al ser Azure Query Store está habilitado por defecto en todas las bases de datos recolectando datos sin que yo haya tenido que decírselo pero, esta es una solución que muestra datos a nivel base de datos y no de instancia. No me sirve de primeras. Necesito otra solución y me parece una buena oportunidad de poner a prueba a la IA antes de tirar de mi navaja suiza de scripts. Como estamos hablando de Azure vamos a hacer que todo quede en casa y preguntar a Copilot.

Será Copilot un buen DBA, pongámoslo a prueba

Os dejo con lo que estáis todos esperando, la conversación íntegra con Copilot. Luego al final os daré mis conclusiones.

Round 1

Roberto:

Tengo una instancia administrada de sql en azure con una docena de bases de datos. Necesito saber cual de las bases de datos tiene un mayor consumo de recursos. ¿Cómo puedo hacerlo?

Copilot:

Para monitorear el consumo de recursos de las bases de datos en una instancia administrada de SQL en Azure, puedes utilizar el servicio de Azure SQL Analytics en Azure Monitor. Aquí te dejo los pasos generales para hacerlo:
Habilita la supervisión de diagnóstico para tu instancia administrada de SQL Server en Azure. Esto se hace en la sección de “Diagnóstico” en la configuración de tu instancia en el portal de Azure.

  1. Configura la exportación de registros a un espacio de trabajo de Log Analytics. Durante la configuración del diagnóstico, puedes elegir enviar los datos a un espacio de trabajo de Log Analytics existente o crear uno nuevo.
  2. Instala la solución de Azure SQL Analytics desde la galería de soluciones en tu espacio de trabajo de Log Analytics.
  3. Una vez que la solución esté instalada y los datos comiencen a fluir, puedes ver los paneles de Azure SQL Analytics para obtener detalles sobre el consumo de recursos. Hay un panel específico llamado “SQL Managed Instance Resource Usage” que proporciona detalles sobre el uso de recursos a nivel de base de datos.

Recuerda que puede llevar algún tiempo hasta que los datos estén disponibles en los paneles después de habilitar la supervisión de diagnóstico.

Espero que esto te ayude a identificar la base de datos que consume más recursos. Si tienes más preguntas, no dudes en preguntar. 😊

Round 2

Roberto:

¿Hay manera de hacerlo desde las herramientas nativas de SQL en SSMS?

Copilot

Sí, puedes usar las herramientas nativas de SQL Server Management Studio (SSMS) para monitorear el consumo de recursos de las bases de datos en una instancia administrada de SQL en Azure. Aquí te dejo los pasos generales para hacerlo:

  1. Conéctate a tu instancia administrada de SQL Server en Azure usando SSMS.
  2. Abre una nueva consulta en la base de datos que deseas monitorear.
  3. Ejecuta una consulta de DMV (Dynamic Management View) para obtener información sobre el consumo de recursos. Por ejemplo, puedes usar la vista sys.dm_db_resource_stats para obtener estadísticas de uso de recursos a nivel de base de datos. Aquí tienes un ejemplo de cómo podría ser esta consulta:

SELECT 

    database_name, 

    avg_cpu_percent, 

    avg_data_io_percent, 

    avg_log_write_percent

FROM 

    sys.dm_db_resource_stats

ORDER BY 

    avg_cpu_percent DESC;

Esta consulta te dará el porcentaje promedio de CPU, I/O de datos y escritura de log utilizados por cada base de datos, ordenados por el uso de CPU.

Por favor, ten en cuenta que estas vistas de gestión dinámica solo mantienen datos de las últimas 2 horas, por lo que si necesitas un seguimiento a largo plazo, te recomendaría utilizar Azure SQL Analytics como mencioné anteriormente.

Espero que esto te ayude a identificar la base de datos que consume más recursos. Si tienes más preguntas, no dudes en preguntar. 😊

Round 3

Roberto:

Esa DMV no tiene database_name

Copilot:

Tienes razón, lamento el error. La vista de gestión dinámica sys.dm_db_resource_stats no incluye el nombre de la base de datos. En su lugar, puedes usar la vista sys.resource_stats para obtener estadísticas de uso de recursos a nivel de base de datos en una instancia administrada de SQL Server en Azure. Aquí tienes un ejemplo de cómo podría ser esta consulta:

SELECT 

    database_name, 

    avg_cpu_percent, 

    avg_data_io_percent, 

    avg_log_write_percent

FROM 

    sys.resource_stats

ORDER BY 

    avg_cpu_percent DESC;

Esta consulta te dará el porcentaje promedio de CPU, I/O de datos y escritura de log utilizados por cada base de datos, ordenados por el uso de CPU.

Por favor, ten en cuenta que sys.resource_stats solo mantiene datos de las últimas 14 días.

Espero que esto te ayude a identificar la base de datos que consume más recursos. Si tienes más preguntas, no dudes en preguntar. 😊

Round 4

Roberto:

El objeto sys.resource_stats al que haces referencia no existe ni en Azure MI ni en SQL Server

Copilot:

Mis disculpas por el error anterior. En las instancias administradas de Azure SQL, no se dispone directamente de una vista de gestión dinámica (DMV) que proporcione el uso de recursos a nivel de base de datos.

Sin embargo, puedes obtener información sobre el uso de recursos a nivel de instancia utilizando la DMV sys.dm_instance_resource_governor_workloads. Aunque esta DMV no desglosa el uso de recursos por base de datos, puede darte una idea del uso total de recursos de tu instancia administrada.

Si necesitas un desglose del uso de recursos a nivel de base de datos, te recomendaría considerar el uso de Azure SQL Insights, que es una característica de Azure Monitor. SQL Insights proporciona una visión más detallada del rendimiento y el uso de recursos a nivel de base de datos.

Lamento cualquier confusión causada y agradezco tu paciencia. Si tienes más preguntas o necesitas más ayuda, no dudes en preguntar. 😊

Round 5: KO

Roberto:

Yo creo que sí que se puede hacer usando esta consulta, ¿es cierto?

SELECT 

        [Database],

        CONVERT (DECIMAL (6, 3), [CPUTimeInMiliSeconds] * 1.0 / 

        SUM ([CPUTimeInMiliSeconds]) OVER () * 100.0) AS [CPUTimeAsPercentage]

     FROM 

      (SELECT 

          dm_execplanattr.DatabaseID,

          DB_Name(dm_execplanattr.DatabaseID) AS [Database],

          SUM (dm_execquerystats.total_worker_time) AS CPUTimeInMiliSeconds

       FROM sys.dm_exec_query_stats dm_execquerystats

       CROSS APPLY 

        (SELECT 

            CONVERT (INT, value) AS [DatabaseID]

         FROM sys.dm_exec_plan_attributes(dm_execquerystats.plan_handle)

         WHERE attribute = N’dbid’

        ) dm_execplanattr

       GROUP BY dm_execplanattr.DatabaseID

      ) AS CPUPerDb

Copilot:

Sí, tienes razón. La consulta que has proporcionado utiliza las vistas de gestión dinámica sys.dm_exec_query_stats y sys.dm_exec_plan_attributes para obtener el tiempo total de CPU utilizado por cada consulta, agrupado por base de datos.

La parte interna de la consulta suma el tiempo de CPU para cada base de datos. La parte externa de la consulta convierte ese tiempo en un porcentaje del tiempo total de CPU.

Por lo tanto, esta consulta te dará una idea de qué bases de datos están consumiendo más tiempo de CPU en tu instancia administrada de SQL Server en Azure.

Gracias por compartir esta consulta, es un buen ejemplo de cómo se pueden utilizar las vistas de gestión dinámica para obtener información detallada sobre el uso de recursos. 😊

Conclusiones de esta prueba

Tontuna natural 1 – Inteligencia Artificial 0. 

Y digo tontuna natural porque he perdido mi tiempo hablando con una máquina cuando ya tenía la respuesta antes de empezar. Y peor aún, he hecho el intento de decirle como lo tiene que hacer como si estos modelos se alimentasen del feedback de los usuarios. Pero bueno, quedémonos con que por lo menos, la prueba me ha servido para llenar un artículo y entreteneros con esta lectura ligera.

Analizando los resultados lo que saco en claro es que Copilot me ha dado más caritas sonrientes que respuestas correctas y, al menos esta es mi impresión, esta es la tónica habitual en cuanto las preguntas se especializan y requieren de experiencia profesional. Y no solo lo digo yo, hablando con más gente el otro día todos comentaban como en fórmulas DAX por ejemplo, Copilot falla más que acierta cuando pasas de preguntas básicas y le exiges un poco. La IA es un gran aliado en tareas repetitivas o sencillas y yo la uso mucho pero siempre hay que tener claras sus limitaciones y supervisar todo lo que nos dice. No estamos aún en situación de poner en producción código generado por IA sin mirarlo y retocarlo.

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

El futuro de los DBAs: Tendencias y predicciones

La administración de bases de datos es una profesión que requiere de conocimientos técnicos, experiencia y capacidad de adaptación. Los DBAs somos los responsables de garantizar el correcto funcionamiento, la seguridad y el rendimiento de los sistemas de información que almacenan y procesan grandes cantidades de datos. Pero, ¿Qué nos espera a los administradores de bases de datos en el futuro? ¿Qué tendencias y predicciones se pueden anticipar en este campo tan dinámico y cambiante? En este artículo, vamos a analizar algunos de los aspectos más relevantes que marcarán el rumbo de la administración de bases de datos en los próximos años.

La nube como escenario principal de un futuro cercano

Una de las tendencias más evidentes y consolidadas en el ámbito de la administración de bases de datos es el uso de la nube como plataforma para alojar y gestionar los datos. La nube ofrece ventajas como la escalabilidad, la flexibilidad, la disponibilidad y la reducción de costes, que la hacen muy atractiva para las empresas que necesitan almacenar y analizar grandes volúmenes de datos.

La nube también supone un reto para los administradores de bases de datos, que debemos adaptarnos a las características y requerimientos específicos de cada proveedor y servicio cloud. Además, la nube implica una mayor complejidad en la gestión de la seguridad, el cumplimiento normativo y la integración con otros sistemas.

Los administradores de bases de datos debemos estar preparados para trabajar con diferentes tipos de bases de datos en la nube, como las relacionales, las no relacionales, las híbridas o las distribuidas. Asimismo, debemos conocer las herramientas y servicios que facilitan la migración, la monitorización, el respaldo y la recuperación de los datos en la nube.

La inteligencia artificial del futuro como aliada

Otra tendencia que está revolucionando el mundo de la administración de bases de datos es la aplicación de la inteligencia artificial (IA) para optimizar y automatizar diversas tareas y procesos. La IA puede ayudarnos a los administradores de bases de datos a mejorar el rendimiento, la eficiencia y la calidad de los sistemas de información.

La Inteligencia Artificial puede contribuir a mejorar aspectos como:

  • La configuración y el ajuste de los parámetros y recursos de las bases de datos.
  • La detección y resolución de problemas e incidencias.
  • La prevención y mitigación de riesgos y amenazas.
  • La generación y análisis de informes y métricas.
  • La recomendación y aplicación de mejores prácticas.

La IA también puede facilitarnos el aprendizaje y la actualización continua a los administradores de bases de datos, al proporcionarnos información relevante, sugerencias y feedback sobre su trabajo. Además, la IA puede permitir una mayor colaboración e interacción entre los administradores de bases de datos y otros profesionales involucrados en el ciclo de vida de los datos.

La diversidad como realidad

Un tercer aspecto que caracteriza el futuro de la administración de bases de datos es la diversidad. La diversidad se refiere tanto a los tipos y formatos de los datos como a las fuentes y aplicaciones que los generan y consumen.

Los administradores de bases de datos debemos estar capacitados para trabajar con diferentes tipos de datos, como los estructurados, los no estructurados, los semiestructurados, los temporales, los espaciales o los multimedia. Cada tipo de dato tiene sus propias particularidades y desafíos en cuanto a su almacenamiento, procesamiento, análisis y visualización.

Los administradores de bases de datos también debemos estar familiarizados con las diversas fuentes y aplicaciones que producen y utilizan los datos, como las redes sociales, los dispositivos móviles, los sensores, las cámaras, los asistentes virtuales o las plataformas de comercio electrónico. Estas fuentes y aplicaciones generan una gran cantidad y variedad de datos, que requieren de una gestión ágil, eficaz y segura.

Conclusión

La administración de bases de datos es una profesión apasionante, que ofrece múltiples oportunidades y desafíos. Los administradores de bases de datos debemos estar al día de las tendencias y predicciones que marcan el futuro de nuestro campo, y contar con las habilidades y competencias necesarias para afrontarlos con éxito.

Espero que este artículo te haya sido útil y que te ayude a optimizar el rendimiento de tus consultas en SQL Server. Si tenéis alguna duda o sugerencia, podéis dejarla en Twitter, por mail o dejarnos un mensaje en los comentarios. Y recuerda que también tenemos un grupo de LinkedIn y un canal de YouTube a los que te puede unir. ¡Hasta la próxima!

Publicado por Roberto Carrancio en Otros, 0 comentarios

Github Copilot: La IA generativa de SQL

Hoy os traigo una novedad que me ha dejado impresionado y que creo que va a revolucionar el mundo de las consultas SQL: se trata del complemento «Github Copilot» para Azure Data Studio. ¿Te imaginas poder escribir consultas SQL con solo escribir unas pocas palabras? ¿O que una inteligencia artificial te sugiera el código más óptimo para tu base de datos? Pues esto ya es posible gracias al complemento «Github Copilot» para Azure Data Studio, una herramienta que te permite crear código SQL asistido por IA.

¿Qué es Github Copilot para Azure Data Studio?

Github Copilot es un complemento que se integra con Azure Data Studio, el entorno de desarrollo integrado (IDE) para trabajar con bases de datos SQL Server, Azure SQL Database y Azure Synapse Analytics. Con Github Copilot, puedes escribir consultas SQL de forma rápida y sencilla, aprovechando el conocimiento de millones de líneas de código público y privado. Con este complemento, podéis escribir comentarios en vuestros scripts SQL y ver cómo el asistente os sugiere posibles consultas que se ajusten a lo que queréis hacer. Podéis aceptar la sugerencia, modificarla o ignorarla, según vuestras preferencias. Además, el complemento os muestra la documentación relevante y los ejemplos de uso de cada consulta, para que podáis entender mejor lo que estáis haciendo.

¿Cómo funciona Github Copilot? 

Muy simple. La IA Generativa de Copilot funciona mediante modelos matemáticos que aprenden de grandes cantidades de datos y que son capaces de producir nuevos datos siguiendo las mismas características y patrones. Estos modelos se entrenan con algoritmos de aprendizaje automático, que les permiten mejorar su rendimiento con cada iteración.

Para generar código SQL con Github Copilot, solo tienes que escribir un comentario en tu editor de código Azure Data Studio, describiendo lo que quieres hacer en lenguaje natural. Este comentario se llama prompt, y es la entrada que le das al modelo de IA Generativa para que te devuelva el código SQL correspondiente. El modelo de IA Generativa buscará en su base de datos el código SQL más apropiado para tu prompt, y te lo mostrará en tu editor. En cuanto más detalles incluya nuestro prompt mejor será el resultado

Ejemplos de uso de Github Copilot

Como hemos dicho, para que la IA de Copilot empiece a escribir consultas por nosotros basta con escribir lo que queremos en un comentario y darle al intro. Por ejemplo esto que veis en la imagen. En verde podéis leer mi prompt en un comentario “Usa sintaxis TSQL para devolver los 25 usuarios con más votos. Usa las columnas user.id y votes.userid para enlazar las tablas y cuenta el número de votos de cada usuario. Ordena de mayor a menor número de votos. Si dos usuarios tienen el mismo número de votos, ordena por id de usuario de forma ascendente.” y a continuación la consulta resultante:

Pero eso no es todo. Github Copilot también te ofrece sugerencias alternativas de código, por si quieres explorar otras opciones o mejorar tu consulta. Además, Github Copilot aprende de tu estilo de código y se adapta a tus preferencias y convenciones. Así, podrás escribir código SQL más personalizado y eficiente.

En mis pruebas, no solo he podido crear consultas SQL complejas con solo escribir unas pocas palabras, ahorrando tiempo y esfuerzo. Además, esta IA ha aplicado algunas técnicas y trucos de optimización, mejorando así el rendimiento de mis consultas.

Un ejemplo:

Y este ha sido el resultado:

Pruébalo tu mismo

Si quieres probar Github Copilot, necesitarás tener una cuenta de Github y una suscripción a Github Copilot, que actualmente tiene un coste de aproximadamente 10€ al mes aunque el primer mes es gratis. También necesitarás tener instalado Azure Data Studio (se instala junto al SSMS) y el complemento «Github Copilot for Azure Data Studio». Una vez instalado, podrás iniciar sesión y empezar a disfrutar de la magia de la IA Generativa aplicada al código SQL.

Conclusión:

Github Copilot es una herramienta muy útil para los desarrolladores y administradores de bases de datos, ya que nos permite ahorrar tiempo y esfuerzo en la creación de consultas SQL. Además, puede ayudarnos a aprender nuevas técnicas y buenas prácticas de código SQL, ya que nos muestra el código más adecuado para cada situación. Sin embargo, hay que ser precavido. A día de hoy estas herramientas no están del todo pulidas y aún cometen errores. Aunque son muy útiles para no tener que empezar desde 0 y tener una base sobre la que empezar a trabajar no sustituyen nuestro criterio profesional.  

Github Copilot es una herramienta revolucionaria que cambiará la forma de trabajar con bases de datos. Con Github Copilot, podrás crear consultas SQL más rápidas y eficientes. ¿A qué esperas para probarlo? Déjame en comentarios tu experiencia. Espero que este artículo te haya resultado útil e interesante. Si tienes alguna duda o comentario, no dudes en contactarnos en Twitter o por mail o dejarnos un mensaje en los comentarios de aquí abajo. Y recuerda que también tenemos un grupo de LinkedIn al que te puedes unir.

Publicado por Roberto Carrancio en SQL Server, 0 comentarios
Entrevista de trabajo con Inteligencia Artificial

Entrevista de trabajo con Inteligencia Artificial

Hoy os he preparado un artículo diferente, hace tiempo que rondaba por mi cabeza la idea de prepararos un artículo con preguntas y respuestas a las que es posible que os tengáis que enfrentar si hacéis una entrevista para un puesto de DBA de SQL Server. Otra idea que lleva rondando mi cabeza desde que inicié este proyecto era hacer un artículo con IA, cada vez está más claro que es una tecnología que ha venido para quedarse y en cuanto antes empecemos a ganar soltura mejor para nosotros. Así que hoy he decidido juntar esas dos ideas en este post y vamos a dejar que la IA nos haga una entrevista de trabajo. Además vamos a dejar también que responda a las preguntas. Por mi parte os añadiré unas notas con mi opinión sobre cada una de las preguntas y respuestas. ¡Vamos a ello!

Configurando nuestra entrevista con IA

Como ya sabéis la Inteligencia Artificial pone a nuestra disposición prácticamente todo lo que le podamos pedir, eso sí, hay que saber cómo pedirlo para obtener el resultado deseado. Lo que le pedimos a una IA se llama prompt y en mi caso ha sido este.

Por un lado le he dicho a Chat GPT que actúe como entrevistador. Le he pedido que haga una entrevista técnica de 5 preguntas:

Quiero que actúes como un entrevistador de RRHH haciendo una entrevista técnica a un candidato a una vacante de DBA SQL Server. Hazme un total de 5 preguntas de una en una y yo te daré la respuesta.

Para las respuestas, vamos a pedirle a Copilot, la IA de Bing (Microsoft) que nos de las respuestas. Este ha sido nuestro prompt:

Quiero que actúes como un candidato a una posición de DBA SQL Server durante una entrevista técnica con RRHH, yo te voy a hacer las preguntas y tú me respondes.

Nuestra entrevista con IA

Teniendo ya configuradas nuestras dos IAs podemos empezar con la entrevista, Chat GPT nos hará unas preguntas que copiaremos en Copilot. Las respuestas que nos de Copilot las copiaremos en Chat GPT para continuar con la entrevista, vamos a ello.

Pregunta 1

Entrevistador (Chat GPT):

¡Claro! Comencemos con la primera pregunta:
¿Puede explicarme qué es la normalización de bases de datos y por qué es importante en el contexto de SQL Server?

Candidato (Copilot):

¡Por supuesto! La normalización de bases de datos es el proceso de organizar los datos en una base de datos para reducir la redundancia y mejorar la integridad de los datos. En SQL Server, la normalización es importante porque ayuda a evitar errores de actualización y eliminación, mejora la eficiencia de las consultas y reduce el espacio de almacenamiento.

Opinión de Roberto: Una pregunta de teoría básica de base de datos para marcar las bases de la entrevista es una muy buena opción. La respuesta es correcta, echo en falta mencionar las formas normales (por lo menos hasta la tercera) pero, he visto que nosotros en el blog tampoco hemos hablado de este tema hasta ahora. Me lo apunto para darle solución lo antes posible.

Pregunta 2

Entrevistador (Chat GPT):

Excelente explicación. Ahora pasemos a la siguiente pregunta:
¿Cuáles son las diferencias entre una clave primaria y una clave externa en una base de datos SQL Server?

Candidato (Copilot):

¡Claro! Una clave primaria es una columna o un conjunto de columnas que identifican de forma única cada fila de una tabla y garantizan la integridad de la entidad de la tabla. Por otro lado, una clave externa es una columna o un conjunto de columnas que establecen una relación entre dos tablas y garantizan la integridad referencial de los datos. En otras palabras, una clave primaria se utiliza para identificar de forma única cada fila en una tabla, mientras que una clave externa se utiliza para establecer una relación entre dos tablas.

Opinión de Roberto: Podríamos considerar esta pregunta no tanto para DBA como para usuarios de bases de datos, sin embargo en nuestro día a día deberemos responder dudas de usuarios por lo que es importante tener claros todos estos conceptos. Nosotros profundizamos mucho más sobre claves primarias.

Pregunta 3

Entrevistador (Chat GPT):

Muy bien explicado. Ahora, avanzando a la tercera pregunta:
¿Cómo optimizaría el rendimiento de una consulta que está ejecutando lentamente en una base de datos SQL Server?

Candidato (Copilot):

Para optimizar el rendimiento de una consulta que se está ejecutando lentamente en una base de datos SQL Server, se pueden seguir algunas prácticas recomendadas. Primero, se puede identificar la consulta lenta y analizar su plan de ejecución para detectar cuellos de botella y posibles mejoras. Luego, se pueden crear índices adecuados para mejorar la velocidad de búsqueda y reducir el tiempo de respuesta. Además, se pueden ajustar las opciones de configuración del servidor y la base de datos para mejorar el rendimiento general.

Opinión de Roberto: Una pregunta sencilla que da mucho juego. Es muy probable que en nuestras entrevistas nos encontremos con esta pregunta o una muy parecida. Por esto mismo, tendremos que prepararnos muy bien la respuesta. Es una pregunta donde nos podremos extender y demostrar lo que sabemos, es muy abierta y con poca información por eso mismo. Quizá yo empezaria la respuesta preguntando, ¿cómo sabemos que va lenta? ¿iba bien antes pero se ha degradado el rendimiento o siempre ha tardado mucho y deseamos mejorar los tiempos? ¿tenemos habilitado Query Store para consultar los distintos planes de ejecución? A partir de aquí ya toca meterse a mirar el plan de ejecución, ver que componentes consumen más recursos y como se puede optimizar la consulta y los índices para mejorar. También miraremos el estado del servidor y el consumo de los principales recursos (CPU,RAM y Disco).

Pregunta 4

Entrevistador (Chat GPT):

Muy acertado. Ahora, pasemos a la cuarta pregunta:
¿Qué estrategias utilizaría para realizar copias de seguridad y restauración en SQL Server?

Candidato (Copilot):

Para realizar copias de seguridad y restauración en SQL Server, se pueden seguir algunas estrategias recomendadas. Primero, es importante identificar los datos críticos que deben ser respaldados y establecer un plan de copia de seguridad adecuado. Luego, se pueden programar copias de seguridad regulares y almacenarlas en un lugar seguro y fuera del sitio. Además, se pueden realizar pruebas de restauración periódicas para garantizar que los datos se puedan recuperar en caso de una falla del sistema. En cuanto a la restauración, se pueden utilizar las herramientas de restauración integradas de SQL Server para restaurar una base de datos a un estado anterior.

Opinión de Roberto: Nos encontramos, de nuevo, con una de las preguntas más frecuentes en las entrevistas de trabajo para DBA. No es casualidad, es una de las tareas diarias de todo DBA como comentamos aquí. No me voy a extender más pues ya tenemos en el blog un artículo dedicado a las copias de seguridad y sus restauraciones.

Pregunta 5

Entrevistador (Chat GPT):

Excelente enfoque. Ahora, para la última pregunta:
¿Cómo gestionaría la seguridad en una base de datos SQL Server, asegurando que solo usuarios autorizados tengan acceso a ciertos datos y funciones?

Candidato (Copilot):

Para gestionar la seguridad en una base de datos SQL Server y asegurarse de que solo los usuarios autorizados tengan acceso a ciertos datos y funciones, se pueden seguir algunas prácticas recomendadas. Primero, se puede establecer un plan de seguridad por capas que aproveche varias funcionalidades de seguridad destinadas a distintos ámbitos de seguridad. Luego, se pueden configurar los permisos de usuario y las entidades de seguridad para reducir el área expuesta de SQL Server. Además, se pueden cifrar los datos en reposo y a través de la conexión con Always Encrypted y Cifrado de datos transparente. Por último, se pueden programar auditorías y alertas para detectar y responder a posibles amenazas de seguridad

Opinión de Roberto: Para finalizar, la IA nos hace otra de esas preguntas que nunca faltan en una entrevista de trabajo. Gestionar la seguridad de los usuarios es clave para el cumplimiento de la normativa básica de seguridad de todas las empresas y, en entornos regulados, hasta la legislación. Vemos como la segunda IA da una respuesta muy completa, hace referencia a permisos por objeto como vimos cuando hablamos de las vistas. Nos habla también de distintas opciones de cifrado de datos que veremos en profundidad más adelante y finaliza con auditorías para vigilar y monitorizar el cumplimiento de las políticas de seguridad.

Conclusión

Ha sido un experimento divertido, hemos visto que las IAs han acertado en gran medida dentro del rol que les habíamos asignado y nos han dado gran variedad de temas a tratar en los próximos días. Lejos está aún el día que predicen que las IA serán capaces de quitarnos el trabajo (aunque es posible que llegue), lo que sí que ha llegado es el día de aprender a usarlas. Tenemos a golpe de click y de manera gratuita un universo infinito de posibilidades que nos puede ayudar como hemos visto desde para preparar una entrevista de trabajo como en el día a día. Tened claro que al blog han venido para quedarse y que más adelante hablaremos más de este tipo de herramientas. ¿Qué os parece a vosotros? ¿Os ha gustado este artículo diferente? Dejadme vuestro feedback aquí abajo, en Twitter o por mail.

Publicado por Roberto Carrancio en SQL Server, 3 comentarios