Rendimiento

¿Cuál es el problema que quieres resolver?

Si hay una pregunta que debería resonar en la cabeza de todo DBA antes de tocar nada es esta: ¿cuál es el problema que quieres resolver?. Parece de sentido común, pero basta con ver la cantidad de “optimizaciones” fallidas que nos encontramos a diario para entender que muchos prefieren actuar primero y pensar después.

No es cuestión de señalar a los juniors recién llegados. También he visto seniors con experiencia aplicar consejos a ciegas porque lo leyeron en un blog (sí, incluso en este). Optimizar sin tener claro el objetivo es la mejor forma de acabar con más índices de los que puedes contar y un servidor que corre peor que antes.

Cuando dos índices son un problema

Hace un tiempo publiqué un artículo en el blog que mostraba un comportamiento extraño en SQL Server: si creas dos índices con los mismos campos pero en orden inverso, el optimizador puede entrar en bucle y empeorar el rendimiento.

No es que uno de los índices fuera inútil, es que la mera coexistencia de ambos confundía al motor. El resultado eran planes de ejecución incoherentes, lecturas disparadas y un servidor que parecía castigar la osadía de haber creado ese segundo índice.

Lo comprobé en mi propio laboratorio y sí, el problema existe en distintas versiones, desde 2014 hasta 2022. No hay explicación oficial, pero el efecto es evidente: un índice que no se usa puede penalizar tanto como uno mal diseñado.

La moraleja es clara: no todo lo que parece buena idea lo es. Crear un índice extra “por probar” puede desatar un problema que no estaba ahí antes.

El optimizador también se equivoca

A ese escenario extraño se suma otro que me he encontrado demasiadas veces: el optimizador sugiriendo crear un índice que ya existe.

¿Cómo puede ser? Muy simple: lo que realmente falla son las estadísticas. Si los datos de distribución están obsoletos, el optimizador cree que no tiene un índice adecuado y recomienda uno nuevo. Y como “buenos DBAs obedientes”, lo creamos. Resultado: en el mejor de los casos acabamos con dos índices redundantes, el motor igual de confundido y el verdadero problema (las estadísticas) intacto. En el peor, con el problema que hemos descrito en el apartado anterior y con las estadísticas aún desactualizadas.

La historia se repite: en vez de preguntarnos qué queremos resolver, nos dejamos llevar por la sugerencia de turno y complicamos aún más el entorno.

Optimizar sin objetivo: el problema más común

Ambos casos ponen de manifiesto lo mismo: aplicar soluciones sin entender el problema real es un deporte de riesgo.

Ya lo comentamos en este otro artículo, los entornos de bases de datos no se arreglan con recetas universales ni con “scripts definitivos” de Internet. Cada entorno es distinto, con sus cargas, sus decisiones históricas y sus miserias. Copiar y pegar soluciones genéricas es más postureo técnico que administración seria.

La optimización sin objetivo es como disparar con los ojos cerrados, con suerte no das en nada, pero la mayor parte del tiempo acabas dañando algo.

La pregunta de Brent Ozar

Aquí entra la insistencia de Brent Ozar en su mantra favorito y que da titulo a este artículo:
¿Cuál es el problema que quieres resolver?

Antes de crear índices, actualizar estadísticas o aplicar hints a lo loco o cambiar configuraciones en el servidor hay que responder a esa pregunta. ¿El problema es el tiempo de respuesta? ¿Consumo excesivo de CPU? ¿Bloqueos? ¿O solo que alguien quiere que una consulta de 3 segundos baje a 0,3 porque sí?

Uno de esos es un problema técnico. El otro es un problema de expectativas. Y mezclar ambos lleva a dedicar horas a optimizar lo que no importa mientras lo urgente sigue sin atenderse.

Si no mides, no sabes si mejoras o empeoras

Aquí está el punto que muchos olvidan, si no sabes que tienes un problema y no mides antes, no puedes saber si lo que hiciste fue una mejora o un desastre.

Un cambio sin línea base no es optimización, es puro azar. Y en producción, jugar al azar es abrir la puerta a que mañana alguien te pregunte por qué el sistema está peor y no tengas respuesta. Sin métricas antes y después, la optimización es indistinguible del postureo.

Y ojo, también tienes que medir cuando todo funciona bien, sin esa linea base es imposible saber si de verdad algo va mal o es solo la sensación de los usuarios. Ya sabemos que adoran decir: “esto ahora va más lento” sin pruebas.

Diagnóstico antes de cirugía

La única forma de trabajar en serio es diagnosticar antes de tocar. Eso implica medir, observar y recopilar evidencia. Query Store, planes de ejecución, Extended Events, DMVs… las herramientas están ahí, pero hay que usarlas con criterio.

El motor se equivoca, los consejos de Internet también, y a veces hasta nuestras “buenas prácticas” son contextuales y no universales. La diferencia entre un DBA que arregla problemas y otro que los multiplica está en hacerse siempre la pregunta incómoda antes de optimizar.

Conclusión

Cambiar configuraciones del servidor, crear índices o aplicar consejos sin diagnosticar el problema real no es optimización, es azar.

SQL Server no premia las soluciones automáticas. Premia el análisis. Y la diferencia entre un DBA que arregla cosas y otro que las rompe está en hacerse siempre esa pregunta incómoda antes de tocar nada: ¿cuál es el problema que quiero resolver?

Si no sabes que tienes un problema y no lo mides antes, no tienes forma de saber si tu cambio fue mejora o desastre. Y en bases de datos, la duda casi siempre juega en tu contra.

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

Novedades sobre el libro

Después de meses de trabajo, revisiones y mucha paciencia, puedo compartir tres novedades clave del libro SQL Server: La NO guía práctica de optimización:

  • El prólogo lo firma Fernando G. Guerrero, pionero en SQL Server y miembro histórico de la comunidad. Además de escribir unas palabras introductorias, ha contribuido en la revisión técnica.

  • Aquí está el índice completo, con los más de 40 capítulos organizados en 7 partes.

  • Y sí: la fecha de lanzamiento ya es oficial. El libro estará disponible a mediados de septiembre. Pronto os diré el día exacto

Índice completo

Parte 1 – Fundamentos del modelo relacional y la arquitectura
Desde la definición de base de datos relacional hasta la estructura física de páginas y archivos. El punto de partida sólido para entender qué hay detrás de cada consulta.

Parte 2 – T-SQL y construcción de consultas eficientes
SELECT, INSERT, UPDATE y DELETE como base, y a partir de ahí subconsultas, CTEs, funciones de ventana, vistas, procedimientos y ejecución de consultas. Todo lo que necesitas para escribir SQL que funcione en producción.

Parte 3 – Transacciones, concurrencia y aislamiento
Propiedades ACID, niveles de aislamiento, bloqueos, deadlocks y el nuevo modelo de bloqueos optimizados. Una sección clave para quien de verdad administre entornos críticos.

Parte 4 – Internals, configuración y mantenimiento
TempDB, almacenamiento, memoria, CPU, cardinalidad, parametrización, índices, estadísticas y particionado. La cocina interna del motor y cómo configurarlo sin hipotecar el rendimiento.

Parte 5 – Backup, recuperación y disponibilidad
Modelos de recuperación, estrategias de backup, restore, Log Shipping, Database Mirroring y Availability Groups. Todo lo que sostiene la continuidad de un entorno SQL Server serio.

Parte 6 – Seguridad y control de acceso
Principales, usuarios, roles, permisos y técnicas avanzadas de seguridad. Desde lo básico hasta RLS, cifrado y enmascaramiento de datos.

Parte 7 – Control, monitorización y diagnóstico
Herramientas internas y externas: Resource Governor, Activity Monitor, DMVs, Profiler, Extended Events, Query Store y PerfMon. Para que no solo administres, sino que entiendas qué ocurre bajo el capó.

Con este índice ya podéis ver que no es un manual de recetas rápidas, sino una guía estructurada de principio a fin para profesionales de SQL Server.

El lanzamiento será a mediados de septiembre y os avisaré en cuanto esté disponible en Amazon.

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

¿Cuál es el coste de no optimizar SQL?

La mayoría de las empresas que trabajan con SQL Server no tienen ni la más remota idea de lo que les cuesta no optimizar sus consultas. Y no, no hablo de la típica pérdida de rendimiento que molesta al usuario de vez en cuando. Hablo de dinero. Del que se escapa cada mes por la rendija del servidor porque nadie se molestó en revisar ese SELECT con JOIN cruzado que parece escrito por un algoritmo con ganas de venganza.

Pero vamos por partes. Porque el drama tiene capítulos, y todos salen caros.

Hardware: más coste para hacer lo mismo (o menos)

Cuando una consulta no está optimizada, lo primero que pide el sistema es más CPU. Más RAM. Más disco. Y como somos humanos, y a veces un poco vagos, el primer impulso es escalar verticalmente: poner más hierro. Total, si ya funciona mal, con más recursos irá mejor, ¿no?

Pues sí. Durante un rato. Luego viene otra consulta igual de mala y vuelta a empezar. El patrón es de sobra conocido: base de datos lenta, compras hardware, mejora temporal, vuelve la lentitud, compras más hardware… y cuando te das cuenta, estás alimentando un monstruo que vive de cores, GB y licencias.

Y aquí entra la broma que siempre duele: SQL Server se licencia por core. Así que cada vez que decides “arreglar” un problema de rendimiento añadiendo CPU, estás aceptando voluntariamente pagar más en licencias, que no son baratas. Es como combatir la sed bebiendo agua salada: parece que ayuda, pero en realidad te estás hundiendo más.

Logo SoyDBA

Únete a la newsletter de SoyDBA

Regístrate gratis para no perderte ninguna novedad. Te avisaré de noticias y eventos importantes

¡No hacemos spam! Lee nuestra política de privacidad para obtener más información.

El coste real en la nube: «elástico», sí, pero hacia arriba

Muchos creen que al migrar a la nube el problema desaparece. Que Azure SQL, AWS RDS o cualquier plataforma PaaS mágica va a solucionar lo que tu SELECT * no quiso arreglar. Y no, no es así.

En la nube todo se factura. Cada milisegundo de CPU, cada MB de RAM, cada GB de almacenamiento y cada IO de disco. Una consulta ineficiente en Azure no solo es lenta: es cara. Muy cara. Porque, a diferencia de tu servidor físico en el CPD, aquí no tienes un coste hundido. Aquí cada operación se convierte en un apunte contable. Y si te pasas, la factura no perdona.

He visto clientes triplicar su consumo mensual de Azure SQL sin añadir ni un solo usuario más. ¿La causa? Un informe mal diseñado, una vista que arrastra medio millón de registros y un desarrollador con más entusiasmo que criterio.

Una historia real de coste en azure

Y luego están los casos como este. Años atrás, un cliente me llamó porque su Azure SQL Managed Instance con 8 cores (unos 1.355€ al mes) tenía la CPU por encima del 90% casi todo el día, con picos constantes al 100% que parecían avisos de incendio. Lo más grave no era eso, sino que ya habían asumido que la única salida era duplicar recursos y pasar a 16 cores, lo que dispararía la factura a 2.700€/mes. Antes de firmar el salto, decidieron llamarme. Por suerte.

Lo que me encontré era un festival del despropósito. Ni un solo índice clustered, todos los índices nonclustered eran de una sola columna y, por supuesto, sin INCLUDE. Mirando el uso, el 95% de esos índices no se usaban. Y claro, la DMV de índices faltantes parecía la lista de tareas de un becario sin supervisión: infinita, desordenada y sin lógica.

Con un par de días de trabajo serio (revisión de patrones de consulta y una política de indexación con sentido común) no solo evitamos el escalado, sino que redujimos la instancia a 4 cores. El resultado fue sorprendente, CPU estable al 30% incluso en horas pico. Lo que se dice, respirar. Pero además, más de 25.000€ al año de ahorro respecto a la solución que estaban a punto de contratar.

El coste del “Pero si se lanza una vez al año…”

Ya que me he puesto en plan cuentacuentos, déjame contarte otra de esas anécdotas que se graban a fuego.

Un día me encontré con un informe, hecho en Tableau (pero eso es lo de menos), que lanzaban una vez al año y que tardaba en completarse… 22 horas. Bueno, yo lo pillé cuando llevaba 22 horas de ejecución en el SQL Server de producción, a saber cuánto más le quedaba. Cuando lo comenté, me dijeron que no pasaba nada, que solo se lanzaba una vez al año y que solían dejarlo corriendo de un día para otro, como quien pone la olla lenta con garbanzos.

Pero yo lo vi claro. La consulta tenía 47 subconsultas en el SELECT. Si, si, CUARENTA Y SIETE. No índices raros, no estructuras marcianas, solo una estructura de consulta absurda.

¿El cambio? Reescribir con LEFT JOIN bien definidos en lugar de esas subconsultas incrustadas. Nada más. Bueno si, una subconsulta que se repetía bastantes veces muy parecida se persistió como temporal al inicio del proceso. De esa manera los datos se leian y filtraban de una tabla grande una sola vez y se quedaban en una tabla pequeña para consultar el resto de las veces. Pero nada más, ni cambiar índices, ni tocar el esquema. Vamos, sin reformar la casa. ¿El resultado? Menos de 20 milisegundos.

Y esto amigos, esto no es una mejora. Eso es pasar de enviar la consulta en burro a ponerle un cohete. Y no exagero.

Porque no todo el coste es culpa del desarrollador

No vamos a demonizar. Todos hemos escrito consultas que después nos dieron vergüenza ajena. Y sí, hay veces que las prisas, las entregas y los deadlines te llevan a empalmar un par de subconsultas “de emergencia” con un UNION sin ALL y a mirar para otro lado.

Pero eso no justifica dejar ese código en producción durante años como si fuera parte del mobiliario. Porque esa consulta, aunque solo se ejecute una vez al día, puede ser la responsable de saturar el servidor, disparar el DTU en Azure o arrastrar a otras aplicaciones con ella.

Aquí entra en juego lo que me gusta llamar “el coste invisible de la desidia técnica”. No se ve, no se presupuesta, pero se paga igual. En horas de soporte, en tiempo perdido, en usuarios frustrados, en reputación quemada.

De 10 minutos a 2 milisegundos (sin efectos especiales)

Otra historia real, por si alguien aún cree que exagero.

Me llama un cliente porque un proceso tarda más de 10 minutos. Revisamos el plan de ejecución y canta como un tenor: falta un índice. Literalmente lo está pidiendo a gritos. Un Clustered Index Scan sobre una tabla de 10 millones de registros con 5 campos varchar(max).

Creamos un índice sencillo sobre los dos campos que busca… y bajamos a 20 segundos. Bien, ¿no?

Pero no me conformé. Me di cuenta de que esos campos varchar(max) apenas se usaban y propuse moverlos a otra tabla. Un cambio mínimo de esquema, sin traumas. El resultado: la consulta se resuelve ahora en 2 milisegundos.

Sí, de más de diez minutos a dos milisegundos. Sin comprar licencias, sin añadir cores, sin tirar la casa por la ventana. Solo sentido común.

Consultas eficientes, bases de datos rentables

Optimizar una consulta no es hacer magia negra ni sacrificar cabras sobre el plan de ejecución. Es técnica, análisis y experiencia. A veces basta con añadir un índice. O con quitar un SELECT * y poner solo las columnas que necesitas. O con evitar ese cursor que llevas arrastrando desde hace 10 años como si fuera un trauma sin resolver.

Una consulta optimizada no sólo corre más rápido. Consume menos CPU. Bloquea menos. Permite que más usuarios trabajen al mismo tiempo. Y, lo más importante, reduce directamente tu coste de infraestructura y licenciamiento.

No es filosofía, son matemáticas puras, si una consulta tarda 500 ms y logra pasar a 50 ms, puedes hacer 10 veces más operaciones con los mismos recursos. ¿Te imaginas que tu equipo hiciera 10 veces más tareas al mismo sueldo? Eso es lo que hace una base de datos bien afinada.

El coste del «si funciona, no lo toques»

Una de las excusas más repetidas cuando se habla de optimizar es: “Pero si ya funciona, ¿para qué meternos ahí?” Pues por eso mismo. Porque ahora va, pero mal. Y cada día que pasa, cada usuario que se conecta, cada nuevo informe que se genera, lo hace un poco peor.

La deuda técnica no caduca. Se acumula. Y cuando salta, no lo hace con un error bonito y fácil de arreglar. Lo hace con un rendimiento desastroso en el peor momento: justo antes del cierre contable, durante el Black Friday o cuando el CEO quiere ver “cómo va todo” desde Power BI (todo casos reales).

Si optimizar parece caro, espera a ver cuánto cuesta no hacerlo.

Formación, experiencia y algo de mala leche

Sí, optimizar lleva tiempo. Requiere saber leer planes de ejecución, entender estadísticas, conocer cómo SQL Server decide qué estrategia usar y cuándo. Pero también requiere actitud. Ganas de escarbar. De no conformarse con que funcione “más o menos”.

Y eso, lamentablemente, no lo da ningún botón mágico ni el asistente del Management Studio. Hay que aprenderlo. O contratar a alguien que lo sepa.

Aquí es donde entra mi parte, claro. No solo como autor de este blog, sino también como consultor. Llevo más de 12 años viendo barbaridades que harían llorar al optimizador de consultas. Y ayudando a equipos a entender por qué sus bases de datos son lentas, y cómo hacer que dejen de serlo sin hipotecar la nube ni sacrificar fines de semana enteros en tareas de mantenimiento que no deberían existir.

Y sí, estoy escribiendo un libro

Mi libro se va a llamar “SQL SERVER: La NO guía práctica de optimización”. Y no será el típico tocho con recetas milagrosas genéricas que nadie es capaz de aplicar en producción. Será un manual honesto, directo y realista. Uno que explica cómo optimizar sin morir en el intento, desde la base y comprendiendo el funcionamiento interno del motor de base de datos. Porque ya tenemos demasiadas presentaciones bonitas que no dicen nada.

Y sí, también haré formación. Y talleres. Y sesiones donde, si hace falta, nos peleamos con los planes de ejecución hasta que canten. Porque se puede. Porque debe hacerse. Y porque seguir pagando licencias por no optimizar… simplemente no tiene sentido.

¿Quieres dejar de pagar por no saber? Hablemos.

Si después de leer esto has pensado en esa consulta que lleva años sin tocar, en ese informe que tarda 12 minutos, o en ese servidor que cada semana pide más cores como si fueran cromos… ya sabes lo que hay.

Puedes seguir ignorándolo, puedes aprender cómo optimizar SQL Server o puedes llamarme y lo miramos juntos.

Tu factura lo va a notar.

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

El mito de los atajos en bases de datos: por qué no hay recetas mágicas

Pocas cosas me generan más frustración que una presentación titulada “10 trucos infalibles para optimizar tu base de datos en 5 minutos”. No porque no quiera rendimiento (lo quiero, y mucho, como todos), sino porque llevo demasiado tiempo en esto como para creer que la administración de bases de datos funciona a base de fórmulas mágicas o guías milagrosas. Cada entorno tiene sus peculiaridades, sus desastres heredados y sus decisiones cuestionables. Pretender que una receta genérica resuelva un problema específico es como recetar paracetamol para un clúster caído. Puede calmar al usuario, pero no soluciona nada.

Atajos en bases de datos que suenan bien pero no funcionan

He visto más veces de las que me gustaría cómo ciertas “técnicas exprés” se convierten en dogmas. Muchas veces aparecen en foros, otras en conversaciones de pasillo, y a veces incluso las incluye algún artículo con demasiadas estrellitas y poca base técnica. Algunas de estas ocurrencias incluso se disfrazan de buenas prácticas, cuando en realidad son puro maquillaje técnico.

Uno de los clásicos eternos es el de desactivar todos los índices antes de una carga masiva. Suena lógico: menos índices, menos mantenimiento durante la inserción. Y puede tener sentido, pero solo si sabemos lo que estamos haciendo. ¿Qué tipo de índices hay? ¿Son realmente necesarios? ¿Cuál es el coste de reconstruirlos después? Porque de nada sirve ahorrar cinco minutos en la carga si luego pasamos tres horas rehaciendo estructuras en plena ventana de mantenimiento (o peor, fuera de ella).

Otro habitual es el uso de hints a ciegas, como si un INNER HASH JOIN fuera una especie de hechizo arcano que mágicamente convierte cualquier consulta en un rayo de luz. El problema, claro, es que el optimizador tiene más información de la que solemos tener nosotros en tiempo de ejecución. Forzar un plan sin pruebas, sin medir, sin entender por qué el motor decide lo que decide, es jugar a ser adivino con el presupuesto de IOPS de otro.

Y por supuesto, no podía faltar el legendario DBCC SHRINKDATABASE, convertido en herramienta habitual de “mantenimiento” por muchos que aún no se han parado a medir sus consecuencias reales. Fragmentación masiva, crecimiento inmediato posterior, tiempos de espera, y un uso de recursos que no compensa ni en entornos de desarrollo, mucho menos en producción. Apretar y soltar el disco como si fuera un globo no libera espacio: solo complica las cosas.

También me topo, de tanto en tanto, con scripts “mágicos” que prometen optimizar todas las consultas de una base de datos con un solo clic. El solo hecho de que alguien los haya escrito ya es preocupante, pero lo que me quita el sueño es que otros los ejecuten sin pararse a pensar. Optimizar no es lanzar un script genérico; es entender, medir, corregir y validar. Todo lo demás es ruido.

La influencia de las redes sociales y los vídeos cortos

En los últimos años, hemos visto cómo el contenido técnico (especialmente en campos con más tracción como ciberseguridad, desarrollo web o administración de sistemas) ha sido invadido por lo que yo llamo la cultura del vídeo de 30 segundos. Esos fragmentos de sabiduría empaquetada en un reel, un TikTok o un hilo de X (antes Twitter, cuando la gente aún sabía debatir sin stickers), donde se vende una técnica como si fuera una revelación divina.

Y aunque parecía que nuestro sector de las bases de datos estaba a salvo de esa superficialidad, cada vez veo más vídeos y publicaciones que sugieren cosas como “optimiza tu SQL Server con este comando”, “el índice que no conocías y te cambiará la vida”, o directamente “el script definitivo para tunear tu instancia”. La cruda realidad es que si usas un script definitivo sin saber qué hace, probablemente estés abriendo un ticket para mí en dos semanas.

¿Que hay gente compartiendo contenido útil? Por supuesto. Pero también hay mucho perfil que ha aprendido a posicionarse en el algoritmo antes que en el execution plan. Lo importante ya no es si lo que dicen tiene sentido, sino si entra bien en vertical, con una música pegadiza de fondo y subtítulos en negrita.

No tengo nada en contra del formato ágil, yo también consumo contenido rápido, pero sí tengo todo en contra de presentar trucos sin contexto, sin advertencias, y sin reconocer que la base de datos no es un entorno de juguete. Es producción. Y producción no se toca a base de “5 tips en 30 segundos”.

El problema no es solo la desinformación. Es que, al repetirse tanto, estos “atajos mágicos” terminan calando. Y entonces llegan al entorno del cliente, del compañero, o al nuestro, envueltos en frases como “vi a un experto decir que esto mejora el rendimiento” o “lo probé en local y funcionó”. El día que alguien monte un clúster con instrucciones de un TikTok, no quiero estar cerca.

La importancia de entender los fundamentos de SQL Server

Lo que realmente marca la diferencia no son los trucos, sino entender qué está pasando dentro del motor. Cuando dejamos de repetir recetas y empezamos a estudiar el comportamiento real de SQL Server, la administración deja de ser un ejercicio de fe y se convierte en una disciplina técnica seria.

Por ejemplo, saber que SQL Server trabaja internamente con páginas de 8 KB nos hace pensar mejor en los tipos de datos, la compresión, la fragmentación y el diseño de índices. Si no entendemos eso, cualquier optimización será como mover las sillas en el Titanic mientras se hunde, entretenido, pero inútil.

También aprendemos cómo funciona el optimizador de consultas, qué espera encontrar, cómo interpreta las estadísticas, y por qué a veces se equivoca. La cardinalidad, ese concepto que a muchos les suena a magia negra, resulta ser clave para entender por qué una consulta se convierte en un escaneo de tabla de millones de filas o en un plan eficiente con pocos milisegundos de CPU.

Y sí, los bloqueos no son enemigos a eliminar. Son síntomas, advertencias, mecanismos de protección. Una transacción larga puede ser más dañina que cien bloqueos bien gestionados. Aprender a leer deadlock graphs, entender niveles de aislamiento y diseñar correctamente el acceso concurrente es mucho más útil que cualquier script que prometa “evitar bloqueos automáticamente”.

Tampoco podemos olvidarnos de las estadísticas. Ejecutar UPDATE STATISTICS porque lo leímos en una lista de tareas semanales es mejor que nada, pero muy lejos de una estrategia de mantenimiento inteligente. Entender cuándo se actualizan, cómo afectan a los planes de ejecución y qué impacto tienen en entornos con muchas escrituras es parte del trabajo que no puede automatizarse con un clic.

Logo SoyDBA

Únete a la newsletter de SoyDBA

Regístrate gratis para no perderte ninguna novedad. Te avisaré de noticias y eventos importantes

¡No hacemos spam! Lee nuestra política de privacidad para obtener más información.

Conocimiento frente a atajos: la diferencia entre arreglar y entender

Aquí es donde la cosa se pone seria. Porque cualquiera puede buscar un error en Google, copiar el primer bloque de código que encuentra y cruzar los dedos. Pero entender el origen del problema, anticipar sus consecuencias y aplicar una solución sostenible y perdurable requiere tiempo, conocimiento y experiencia. Y eso no se compra ni se descarga.

Cuando tengo que elegir entre arreglar algo deprisa o entender por qué está roto, prefiero lo segundo. Porque arreglar sin comprender es pan para hoy y desastre para mañana. Ya nos conocemos ese guion: parche rápido, alivio temporal, y dentro de una semana… el mismo problema, pero más grande.

Los atajos, en general, no resuelven nada. Solo tapan síntomas. Como esa costumbre de algunos de hacer REBUILD INDEX sin mirar estadísticas de fragmentación, sin diferenciar índices columnstore y sin medir el impacto real en el rendimiento. Más mantenimiento no siempre es mejor mantenimiento. A veces es solo ruido.

Conclusión

Si algo tengo claro después de más de una década en esto es que los milagros no existen en administración de bases de datos. Hay herramientas útiles, sí. Hay buenas prácticas, también. Pero no hay soluciones universales. Y cada vez que alguien actúa como si las hubiera, lo único que consigue es complicar aún más el trabajo de quienes venimos detrás a recoger los pedazos.

SQL Server no premia al que improvisa, sino al que entiende. No necesitamos más scripts mágicos, necesitamos más análisis, más diagnóstico, más contexto. Y sobre todo, más respeto por el conocimiento técnico. Porque al final, el rendimiento real no llega por hacer más clics, sino por hacer las preguntas correctas y saber interpretar las respuestas.

Así que, si alguien te promete un truco definitivo para que tu base de datos vuele, recuerda: también hay quien promete que los cursores funcionan bien. No les creas.

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

¿Trabajar 15 horas (o menos) a la semana como DBA? Depende del tipo de DBA que seas

Hace poco, Brent Ozar publicó un artículo comentando una conversación en Reddit que planteaba una pregunta tan ingenua como recurrente: ¿de verdad hay DBAs cobrando un pastizal por trabajar 15 horas a la semana mientras el resto del tiempo ven vídeos o están “de guardia”?

Spoiler: sí, pero no es lo habitual, ni llega de la nada, ni cualquiera puede aspirar a eso. El artículo analiza muy bien los matices detrás de ese escenario, y ya que yo llevo más de una década trabajando con SQL Server, quiero aportar mi perspectiva sobre cómo se vive esto aquí. Porque el contexto importa, y mucho.

DBA de Infraestructura vs DBA de optimización

En el mercado español, y esto lo digo por experiencia directa, los perfiles DBA suelen dividirse claramente entre los que se encargan de la infraestructura y los que nos centramos en la optimización. Los primeros están más cerca del mundo sysadmin: alta disponibilidad, backups, parches, clústeres, automatización de tareas rutinarias. Los segundos vivimos más pegados al código: tuning de queries, revisión de planes de ejecución, diseño de índices y control del rendimiento.

Ahora bien, los que realmente marcamos la diferencia somos los que hemos aprendido a movernos en ambos mundos. Ese es el perfil que he desarrollado con los años y al que creo que todos deberíamos aspirar. No tiene sentido saber montar un AG perfecto si luego no detectas un SELECT * a pelo en una tabla de 300 millones de filas. Y viceversa.

El entorno lo define todo: DBA interno vs. DBA externalizado

Otra diferencia clave, y que marca el tipo de trabajo que hacemos, es si estamos dentro de un cliente final o trabajamos en una consultora o equipo de soporte multicliente.

Yo he pasado por ambos mundos, y la diferencia es abismal. Cuando estás en cliente final, con un parque de servidores limitado (pongamos menos de 20), tienes margen para hacer las cosas bien. Puedes auditar el entorno, meter procesos de automatización, eliminar errores históricos y acabar interviniendo en decisiones de diseño. Incluso te conviertes en un filtro obligado antes de subir cambios a producción.

Después de ese primer año o dos de “puesta a punto”, el trabajo se estabiliza. Las incidencias bajan, los entornos están controlados y puedes dedicar tiempo a tareas de más valor. A veces, incluso, te conviertes en esa figura que aparece poco… pero cuando aparece, es por algo serio.

En cambio, cuando estás en un cliente grande o en una consultora gestionando cientos o miles de servidores, el enfoque cambia. Hay que actuar por patrones, automatizar a escala y asumir que no vas a conocer cada entorno al detalle. Te pasas más tiempo apagando fuegos que optimizando consultas. Lo urgente gana a lo importante, y profundizar se convierte en un lujo.

¿Y los desarrolladores que ejercen de DBA?

Aquí conviene puntualizar. Existen desarrolladores SQL que asumen funciones de DBA y lo hacen bien. He trabajado con varios y sé que hay perfiles muy sólidos que entienden el motor, cuidan el rendimiento, diseñan esquemas con criterio y se preocupan por el coste real de sus consultas.

Este artículo también va por ellos. Porque son, en esencia, parte del mismo ecosistema. Saben lo que hacen, aunque su tarjeta no ponga “DBA”.

Ahora bien, también todos hemos visto el otro extremo, equipos donde nadie tiene perfil de base de datos y se asume que “el que más sabe de SQL” llevará los servidores. En esos casos, se sobrevive como se puede. Backups por defecto (con suerte), configuraciones sin revisar y scripts de producción lanzados con los dedos cruzados.

No es raro ver scripts de mantenimiento programados en el Post-it Engine, versión papel pegado al monitor. Y la documentación vive, cómo no, en la bandeja de entrada de alguien que ya no está en la empresa.

No es raro, pero no es lo que nos interesa hoy. Aquí estamos hablando de roles expertos. De gente que sabe lo que es un latch y por qué TEMPDB puede ser un cuello de botella aunque no tenga muchos datos.

¿Trabajar 15 horas o menos a la semana como DBA? Sí, pero no como te imaginas

Lo que cuenta Brent sobre ese DBA que trabaja 15 horas a la semana o menos y el resto del tiempo está en “modo guardia” es perfectamente posible. Pero no es un privilegio aleatorio, ni una herencia. Es el resultado de años de trabajo bien hecho.

Yo he estado en esa posición. He tenido entornos donde, después de automatizar, revisar, auditar y consolidar, apenas había incidencias. Y cuando las había, las resolvía rápido. No porque tuviera suerte, sino porque conocía el entorno al detalle.

En esos escenarios, no estás “siempre productivo”. De hecho, a veces ni siquiera un 10% del tiempo. Pero cuando hay un problema, tu intervención marca la diferencia. No puedes dudar, no puedes consultar la documentación. Tienes que actuar con precisión y rapidez. Porque si tardas 30 minutos más de la cuenta, el sistema de ventas se cae, el almacén se para o la factura al cliente se multiplica por dos.

No estás al 100%. Ni falta que hace. Estás como los extintores: colgado en la pared, sin moverse, hasta que alguien grita y hay que actuar. Solo que tú sabes más de índices que de espuma.

Este tipo de puesto no es para cualquiera. Y desde luego, no es un trabajo cómodo. Es un rol de alta responsabilidad y alta exigencia, aunque no lo parezca desde fuera.

¿El rol del DBA está en peligro?

Llevamos años oyendo que el DBA está muerto. Que si la nube automatiza todo, que si los desarrolladores se bastan solos, que si la IA lo va a arreglar todo con cuatro sugerencias inteligentes.

La realidad es que el rol está cambiando, no desapareciendo. Los DBAs de infraestructura han tenido que evolucionar hacia entornos híbridos, servicios PaaS, IaC, automatización. Pero los problemas siguen existiendo, solo que tienen otro nombre.

Y los DBAs de optimización somos ahora más importantes que nunca. Especialmente en entornos cloud, donde cada milisegundo extra tiene un precio literal. Cuando un SELECT mal optimizado empieza a generar 30 euros por hora de DTUs, todo el mundo mira al DBA. No al desarrollador, no al arquitecto, no al jefe de proyecto. A nosotros.

DBA cada segundo cuenta

Las herramientas (de IA o no) que prometen optimizarlo todo aún están lejos de ser útiles, al menos sin intervención. Usamos Copilot, sí. Pero lo que da miedo no es lo que sugiere, sino que alguien lo acepte sin parpadear.

Copilot a veces acierta… como un reloj parado. Dos veces al día, da una respuesta aceptable. El problema es todo lo que sugiere entre medias.

Saber distinguir el buen consejo del disparate es, y seguirá siendo, trabajo nuestro.

Conclusión: menos horas, más impacto

Trabajar 15 horas a la semana o menos no significa trabajar poco. Significa haber llegado a un punto donde aportamos valor real justo cuando hace falta.

No estamos todo el día productivos. Pero cuando algo revienta, actuamos con decisión. Y eso solo se consigue con años de experiencia, conocimiento técnico profundo y sangre fría. Porque cada minuto cuenta cuando la producción está caída.

El puesto de DBA no está en peligro. Lo que está en peligro es seguir pensando que esto va de hacer backups y mirar gráficas. El futuro es de los que afinan, automatizan y cuando hay que actuar… no preguntan, resuelven. Y sí, puede parecer que no hacemos mucho. Pero cuando hacemos, salvamos el día, la semana y la cuenta de resultados de la empresa. Y eso vale más que cualquier KPI de los Project Manager.

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

Page Split: el invitado indeseado en SQL Server

Hay conceptos en SQL Server que son como ese compañero de trabajo que nadie ha invitado a la reunión pero que aparece, opina y encima se queda a tomar café. Los Page Split son ese compañero. Y lo peor de todo es que, en muchos casos, somos nosotros los que, sin querer, les abrimos la puerta. En este artículo vamos a diseccionar qué son, por qué ocurren, cómo detectarlos y, sobre todo, cómo podemos hacerles la vida difícil para que molesten lo menos posible.

Qué demonios es un Page Split

Cuando hablamos de Page Split en SQL Server nos referimos a un fenómeno que ocurre cuando el motor de base de datos necesita insertar un registro en una página de datos (o de índice) que ya está llena. Como SQL Server trabaja con páginas de 8 KB (sí, esa unidad tan entrañable que nos acompaña desde hace décadas), llega un momento en el que no hay espacio para ese nuevo registro. Entonces, el motor se ve obligado a dividir la página en dos: mueve aproximadamente la mitad de las filas a una nueva página y deja espacio en la original para la nueva inserción. Esto es el famoso Page Split.

Hasta aquí podría parecer un mecanismo inteligente y útil. Y lo es, en teoría. El problema es el impacto que tiene: incremento del número de páginas (y por tanto del tamaño del índice), fragmentación lógica, más operaciones de I/O, y un rendimiento que empieza a cojear como un servidor sin mantenimiento en una década.

Cuándo y por qué ocurre el Page Split

La causa principal de un Page Split es el uso de claves que no son secuenciales en índices clustered o nonclustered. Insertar valores intermedios en el orden lógico del índice fuerza al motor a abrir hueco donde no lo hay. Por ejemplo, si tenemos un índice clustered sobre un campo Nombre y estamos insertando valores aleatorios, SQL Server tendrá que hacer malabarismos para mantener el orden lógico.

Claro, alguno podría pensar: “Esto con un índice clustered en una clave IDENTITY no pasa”. Efectivamente, las claves secuenciales como IDENTITY, NEWSEQUENTIALID() o datetime en inserciones crecientes suelen evitar la mayoría de los Page Split. Pero ojo: incluso con claves secuenciales, si empezamos a hacer updates que ensanchan las filas más de lo que la página puede aguantar, también podemos provocar splits. Porque sí, los Page Split no son sólo cosa de INSERT, también los UPDATE pueden invitar al desastre si agrandan las filas.

Cómo afectan al rendimiento (y al ánimo del DBA)

Los Page Split producen fragmentación interna y externa. Interna porque dejan huecos en las páginas; externa porque el orden lógico del índice ya no se corresponde con el orden físico. Esto se traduce en más lecturas para recuperar los datos, más uso del log de transacciones y, en general, más I/O. Y todos sabemos que el disco es, casi siempre, el cuello de botella por donde mueren los sueños de un servidor bien optimizado.

Por si fuera poco, cada Page Split genera actividad en el log de transacciones: hay que registrar la creación de la nueva página, el movimiento de filas y la actualización de punteros. Si tenemos una base de datos en modo FULL, el crecimiento del log puede ser un espectáculo digno de verse (si uno disfruta con los desastres).

Cómo detectar Page Split

Como sabes, lo que no se mide no se puede optimizar, lo bueno es que detectar los Page Split no es complicado si sabemos dónde mirar. Un sitio clásico es el contador de rendimiento SQLServer:Access Methods – Page Splits/sec. Si ese contador empieza a dar cifras escandalosas, es momento de investigar.

Otra opción es recurrir a las DMV. La vista sys.dm_db_index_physical_stats nos permitirá ver el grado de fragmentación de los índices. Un índice muy fragmentado suele ser un buen candidato a tener Page Split en su historial reciente. Y si queremos verlos en tiempo real, un Extended Event como page_split o sqlserver.page_split, según versión, nos dará información jugosa sobre cuándo y dónde están ocurriendo.

Sí, podemos hacerlo también con Profiler, pero sinceramente, a estas alturas quien siga usando Profiler en producción para esto se merece un Page Split en su jornada laboral.

Cómo prevenir los Page Split

Es mejor prevenir que curar, siempre. La primera y más efectiva estrategia es diseñar bien las claves de los índices. Un índice clustered sobre un campo secuencial es nuestro mejor amigo. Esto evita la mayor parte de los Page Split derivados de inserciones.

Otra técnica clásica es jugar con el FILLFACTOR. Cuando creamos o reconstruimos un índice podemos indicar un valor de Fillfactor que deje un porcentaje de espacio libre en las páginas (por ejemplo, un 90% en vez del 100% por defecto). Esto da margen a que nuevas inserciones se acomoden sin provocar un split inmediato. Claro, no es gratis: el índice ocupará más espacio y necesitaremos más memoria y más I/O. Pero al menos los splits no nos atacarán a traición.

Eso sí, cuidado con el Fillfactor. Poner un Fillfactor bajo indiscriminadamente es como invitar al primo gorron a casa: puede aliviar al principio pero al final nos pasa factura. Hay que medir, probar y ajustar.

Y no olvidemos las operaciones de mantenimiento: reconstruir o reorganizar los índices periódicamente ayuda a reducir la fragmentación causada por los Page Split. Aquí no vamos a descubrir nada nuevo, pero sí recordar lo evidente: el mantenimiento es como lavarse los dientes; si no lo haces, el problema llegará y será feo.

Casos reales y conclusiones claras

En entornos OLTP con claves no secuenciales he llegado a ver índices con más del 70% de fragmentación en menos de una hora de actividad. La consecuencia era un aumento de I/O y un rendimiento que hacía llorar al más curtido. ¿La solución? Cambio de diseño de clave, ajuste del Fillfactor y un plan de mantenimiento digno.

En entornos con cargas masivas de datos desordenados, lo ideal es insertar en tablas heap (sin clustered) y luego aplicar el índice clustered al finalizar, o bien usar particiones y cargas ordenadas. Porque sí, hay vida más allá de pelearse con Page Split en cada carga.

En definitiva, los Page Split son inevitables en determinados escenarios, pero podemos hacer mucho para mantenerlos a raya. El diseño de los índices, el Fillfactor y un mantenimiento adecuado son nuestras principales armas. Y no, el truco no está en hacer rebuilds cada noche a lo loco; está en entender el porqué y el cuándo, y actuar con cabeza.

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

El problema del Reenvío de punteros en tablas heap

Hoy vamos a hablar de un fenómeno tan molesto como habitual en ciertos entornos: el reenvío de punteros en tablas heap de SQL Server. Sí, ese “detalle” que suele pasar desapercibido hasta que un día nuestras consultas empiezan a ir como un carro tirado por burros, y claro, toca ponerse el traje de bombero.

Antes de entrar en harina, pongamos un poco de contexto. Las tablas heap, esas nobles estructuras sin índice clustered, a veces se eligen por necesidad, otras por ignorancia y, en los peores casos, porque alguien tenía prisa por entregar y pensó que ya lo arreglaríamos después.Y claro, luego nunca se arregla. Y mientras tanto, los forwarded records o reenvíos de punteros campan a sus anchas.

¿Qué es un reenvío de punteros y por qué debería importarnos?

Cuando una tabla no tiene índice clustered, SQL Server guarda las filas donde buenamente puede. Sin ese ordenamiento y estructura que un clustered impone, el heap es un campo abierto. Hasta aquí, todo bien. El problema aparece cuando actualizamos una fila y esa nueva versión no cabe en la misma página. ¿Qué hace SQL Server? ¿Mover toda la fila a otra página y actualizar los punteros que la referencian? Ojalá. Lo que hace es dejar un puntero en la ubicación original que apunta a la nueva ubicación de la fila. Ese es el reenvío de puntero: un salto innecesario que se añade al acceso de la fila.

Esto, que puede parecer inofensivo en pequeñas dosis, se convierte en un verdadero problema cuando la tabla crece y las modificaciones son frecuentes. Cada reenvío implica un acceso extra a disco o memoria para encontrar la fila real. Y como bien sabemos, esos accesos extra no son gratuitos: incrementan el tiempo de lectura y degradan el rendimiento de las consultas. Especialmente en esas tablas que alguien decidió consultar con un SELECT * y sin WHERE, porque total, ¿qué podría salir mal?

Cómo se genera un reenvío de punteros

Veámoslo en acción. Tenemos una tabla heap. Insertamos filas. Todo perfecto. Llega el día en que un UPDATE aumenta el tamaño de una fila (añadimos datos a una columna VARCHAR, por ejemplo). La fila ya no cabe en su página. SQL Server mueve la fila a una nueva página y deja un puntero en la posición original apuntando a la nueva ubicación. Algo así como el cartel de nos hemos mudado que ponen algunos negocios en su antiguo local cuando cambian de ubicación. Ahora acceder a esa fila implica primero leer la página con el puntero, luego saltar a la nueva página y leer la fila real. Siguiendo con el ejemplo anterior es como si el GPS te llevase al local antiguo para que vieses el cartel y tuvieses que ir al nuevo.

Pero es que la fiesta no termina ahí. Si la fila se vuelve a actualizar y tampoco cabe en su nueva página, obtenemos un reenvío de un reenvío. ¿Bonito, verdad? Sí, tan bonito como ese fragmento lógico que nadie defragmenta porque “total, no pasa nada”.

Impacto en el rendimiento de los reenvíos de punteros

El impacto de los reenvíos de punteros se manifiesta principalmente en las operaciones de lectura. Cada reenvío supone al menos un salto adicional. Si tenemos un número considerable de ellos, nuestras lecturas se convierten en una gincana de páginas de datos, con sus correspondientes cache misses, latches y demás alegría. Pero no creas que las escrituras están exentas, recuerda que antes de escribir casi siempre lees.

Esto no solo afecta a la velocidad de las consultas. También incrementa el uso de CPU, el tráfico de I/O y la presión sobre el buffer pool. Y aquí viene el detalle que más nos gusta: el optimizador de consultas no tiene en cuenta el coste de los reenvíos al planificar. Así que podemos tener un plan que parecía estupendo sobre el papel y que en ejecución se arrastra como un SELECT con hints absurdos.

Cómo detectar el reenvío de punteros

Detectar reenvíos de punteros no es complicado, pero requiere mirar donde hay que mirar. Podemos usar sys.dm_db_index_physical_stats con la opción DETAILED para analizar las tablas heap y ver el número de forwarded_records. Si este número empieza a crecer, es hora de preocuparse.

Un ejemplo de consulta para los amigos de lo rápido y directo:

Esto nos da una idea de cuántos reenvíos tenemos por tabla. Si ese número no es cero, tenemos trabajo pendiente. Y si el número es alto, es probable que también tengamos un problema de rendimiento.

¿Como elimino los reenvíos de punteros?

La primera solución (y la más eficaz) es: no uses heap salvo que tengas un motivo sólido para hacerlo. Si la tabla tiene lecturas frecuentes y actualizaciones que modifican el tamaño de las filas, un índice clustered es casi siempre mejor elección. Sí, incluso aunque esa tabla sea de staging y “solo esté ahí un ratito”.

Si por algún motivo tenemos que seguir con el heap, toca plan de mantenimiento especial. Por norma general, los planes de mantenimiento de índices no nos van a servir. En su lugar, tenemos que usar el comando ALTER TABLE [NombreTabla] REBUILD que reconstruye el heap y elimina los reenvíos de puntero. Pero claro, eso implica bloqueo de tabla (en algunas versiones de SQL) y no es algo que uno quiera hacer en mitad de un horario productivo.

Otra opción es rediseñar el esquema de la tabla para minimizar las columnas de longitud variable que crecen sin control. Porque claro, si tenemos un VARCHAR(8000) para guardar un número de teléfono “por si acaso”, el problema no es el heap: el problema somos nosotros.

Y por supuesto, monitorizar. Tener un job que periódicamente revise el número de forwarded_records y alerte si se dispara es una medida sencilla que nos puede ahorrar muchas sorpresas.

¿Hay situaciones donde el heap tenga sentido?

Sí, existen. Por ejemplo, en tablas de staging para cargas de datos donde no se hacen actualizaciones y los datos se procesan y eliminan rápidamente. Ahí un heap puede funcionar bien. Pero claro, en cuanto se empieza a hacer algún UPDATE, la decisión de no poner un clustered se vuelve difícil de defender. Y no, el argumento de “es que así insertamos más rápido” no vale si luego el rendimiento de las consultas se va al traste.

Conclusión

El reenvío de punteros es un mecanismo interno de SQL Server para lidiar con el crecimiento de filas en tablas heap. No es un bug, es un diseño consciente. El problema es que suele aparecer porque tomamos decisiones de diseño pobres o porque descuidamos el mantenimiento. Si tenemos un heap, debemos ser conscientes de las implicaciones y monitorizar su estado. Y si vemos reenvíos, actuar antes de que el rendimiento se desplome.

Como siempre, lo más efectivo es evitar el problema desde el principio. Un índice clustered bien elegido elimina de raíz el riesgo de reenvíos. Y si alguien nos insiste en que un heap es la mejor opción para esa tabla con 500 millones de filas y actualizaciones frecuentes, siempre podemos sugerirle que haga las pruebas en producción. Total, ¿qué podría salir mal?

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