Bases de datos en contenedores – SQL Server en Windows

Este artículo es el primero de una serie sobre bases de datos en contenedores. Por ello, empezaremos revisando qué es un contenedor, para luego entrar en nuestro primer caso: SQL Server en contenedores Windows.

¿Qué es un contenedor?

Cuando hablamos de contenedores, hablamos de virtualización a nivel de sistema operativo. Con este método, el núcleo (o kernel) del Sistema Operativo permite que existan varias instancias de espacio de usuario, aisladas unas de otras, de manera que cada instancia parece un servidor real para los procesos que hay en su interior. A estas instancias se les llama contenedores.

La principal diferencia con las máquinas virtuales (VMs) es que éstas ejecutan un Sistema Operativo completo, y requieren de asignación de recursos (CPU, memoria y almacenamiento) de la máquina que hospeda. Por otro lado, los contenedores no requieren un SO dedicado, y por tanto son más ligeros que las VMs.

Fuente: Wikipedia

Los contenedores no son algo nuevo, en UNIX surgió chroot, considerado por muchos un precursor del contenedor, a comienzos de los 80s. Sin embargo, fue al inicio de los 2000, cuando aparecieron varios proyectos importantes de contenedores para Linux y Windows como VServer, Sandboxie o Virtuozzo, por mencionar algunos ejemplos.

Pero no es hasta el 2013 cuando Docker sale a la luz y comienza una revolución en la industria de la ingeniería del software, adoptándose el uso masivo de contenedores.

¿Por qué contenedores?¿Por qué Docker?

Recuerdo hace varios años cómo hacer que tu aplicación funcionase en la máquina de un compañero podía complicarse de forma inimaginable. Si era problema de que faltaba una librería o la versión exacta de cierto componente, driver, etc, por citar solo algunas variables, solía llevar tiempo y dolores de cabeza hacerlo funcionar. En general, esto obligaba a contar con una documentación detallada para la instalación de la aplicación. Y no siempre se contaba con esa documentación o no estaba lo suficientemente actualizada.

Docker permite crear fácilmente aplicaciones y encapsularlas en contenedores. Gracias a que el contenedor tiene todo lo que la aplicación necesita para ejecutar, permite a los desarrolladores compartir fácilmente sus aplicaciones, hace más fácil las fases de pruebas y permite despliegues más sencillos, rápidos y fiables de la aplicaciones.

SQL Server en contenedores Windows

Cuando necesitamos desarrollar y probar scripts de base de datos, normalmente queremos probarlo en un entorno aislado para que lo que hagamos no afecte al resto de personas del equipo y viceversa. Lo ideal es que este entorno aislado sea nuestra máquina, en local. Para trabajar de esta manera necesitamos tener el servidor de SQL Server instalado y configurado. Esto no es sencillo, suele conllevar varios pasos manuales, y no se trata de una tarea de minutos, sino más bien de horas.

Vamos a ver los pasos que podemos seguir para hacerlo con contenedores:

1) Instalar Docker Desktop

Docker nos recomienda usar Docker Desktop para Windows. Sigue estos dos puntos:

  • Comprueba que tu equipo cumple con los requisitos mínimos.
  • Si lo anterior se cumple, procede con la instalación. Sigue los pasos detallados en esta página del docker hub.

Una vez hayas instalado Docker Desktop, deberíamos verificar que funciona correctamente. Abre una consola de PowerShell como administrador y ejecuta estos comandos:

# Mostramos las versiones del docker client y del docker server
docker version

# Descargamos una imagen pública llamada hello-world del docker hub
docker image pull hello-world

# Probamos que docker funciona correctamente usando la imagen que acabamos de descargar
docker container run hello-world

Comentar que en el anterior comando podríamos haber usado docker run hello-world sin container, pero

2) Crear el contenedor con SQL Server

Descargamos del docker hub la imagen del contenedor que usaremos. Se trata de una imagen pública creada por Microsoft y llamada mssql-server-windows-developer:

docker image pull mssql-server-windows-developer

Este paso de descargar la imagen de la red, no es estrictamente necesario, ya que con “docker container run…” también podemos descargar la imagen si aún no la tenemos. Ahora podemos seguir básicamente dos métodos:

A) Esta es una opción más inmediata, pero los valores de los parámetros están pasados por la línea de comandos, y tendrás que volver a escribir todo la próxima vez que quieras usarlo.

docker container run -e "ACCEPT_EULA=Y" -e "sa_password=XXXXXXXX" -e "MSSQL_AGENT_ENABLED=true" --name bonisql -p 31433:1433 -d microsoft/mssql-server-windows-developer

B) Usando fichero de parámetros, primero vamos a definir una serie de variables que usaremos como parámetros durante la creación del contenedor de MSSQL.

Elegimos una ruta de trabajo y desde nuestra consola, navegamos hasta ella y ahí creamos un archivo con todas las variables. Puedes ver un ejemplo en mi página de github: ps_container_creation_variables_mssql.ps1. Mi consejo es que lo personalices a tu gusto.

A continuación, el siguiente script que vamos a usar, ps_docker_run_mssql.ps1, lo tienes disponible en el mismo repositorio, y una vez lo revises, está listo para ser ejecutado:

cd tu_ruta_de_trabajo
.\ps_container_creation_variables_mssql.ps1
.\ps_docker_run_mssql.ps1
docker container list    # equivalente a: docker ps --all 

3) Conectarnos a nuestro SQL Server contenerizado

Para esto necesitaremos saber la dirección IP que Docker ha asignado a nuestro contenedor. Podemos ver esto de varias formas, por ejemplo con cualquiera de los siguientes dos comandos:

docker container inspect bonisql
docker container inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' bonisql

El primero te devuelve la configuración completa del contenedor, mientras que el segundo retorna exactamente lo que buscamos.

Sabiendo la IP, el puerto, y las credenciales que usamos durante el docker container run, ya tenemos todo lo necesario para conectar a nuestra instancia de MSSQL, a continuación pongo dos ejemplos:

a) Usando SSMS

Merece la pena mencionar, que también podría valer usar la IP de nuestra máquina, host u hospedador, pero cambiando al puerto que se usó durante docker container run. Ejemplo: Para -p 31433:1433 podríamos usar cualquier de las siguientes opciones:

  • IP_del_contenedor,1433
  • IP_del_contenedor (ya que 1433 es por defecto)
  • IP_del_host,31433

b) Usando powershell

$ConnectionString = "Data source=172.19.240.100;Initial Catalog= master;User Id=sa;Password=XXXXX"
Invoke-Sqlcmd -ConnectionString $ConnectionString -Query "SELECT 1"

Y una vez conectados a nuetro SQL contenerizado, podemos crear una base de datos, crear tablas, ejecutar consultas, etc. Cómo en cualquier otro servidor!

4) Configuración avanzada

Todo lo anterior nos cubre lo básico para empezar a usar contenedores de MSSQL en Windows. Pero ¿Y si queremos más? Y si queremos…

  • Asignar una IP fija a nuestro contenedor.
  • Configurar el servicio SQL Agent y otros.
  • Restaurar una copia de seguridad de una base de datos.
  • Hacer que los cambios en la base de datos persistan.

Vayamos por partes entonces…

Asignar una IP fija a nuestro contenedor

Cuando se instala Docker Desktop y se inicia el servicio de docker en Windows, se debe crear de forma automática una red de tipo NAT en docker. Se puede identificar con el siguiente comando:

docker network ls

Para consultar la subred asociada a nat podemos usar:

docker network inspect --format='{{range .IPAM.Config}}{{.Subnet}}{{end}}' nat

Si por alguna razón la red virtual no existiese, la podemos crear:

docker network create --driver=nat dockerlab_network --subnet=172.19.240.0/20 --gateway=172.19.240.1

Sabiendo el rango IP de la subred, podemos asignar una dirección y usarla en nuestro script para ejecutar el contenedor:

$env:mssql_container_network = 'nat'
$env:mssql_container_ip = '172.19.240.100'
.\ps_container_creation_variables_mssql.ps1
docker run -e "ACCEPT_EULA=$env:mssql_container_eula" `
-e "SA_PASSWORD=$env:mssql_container_sa_passw" `
-e "MSSQL_AGENT_ENABLED=$env:mssql_container_agent" `
--name $env:mssql_container_name `
--network $env:mssql_container_network `
--ip $env:mssql_container_ip `
-p $env:mssql_container_port `
-d $env:mssql_container_image

Configurar el servicio SQL Agent y otros

Por defecto cuando creamos nuestro contenedor, el SQL Agent viene deshabilitado. Por lo tanto necesitamos añadir la opción -e “MSSQL_AGENT_ENABLED=true”, como hicimos en el paso 2) anteriormente. Pero aún así, hace falta iniciar el servicio. Lo podemos hacer de la siguiente forma:

# Comprueba los servicios iniciales
docker container exec $env:mssql_container_name powershell.exe /C "Get-Service *SQL* | Select-Object status, name, displayName, StartType"

# Para y deshabilita los que no interesen
docker container exec $env:mssql_container_name powershell.exe /C "Stop-Service SQLTELEMETRY"
docker container exec $env:mssql_container_name powershell.exe /C "Set-Service SQLTELEMETRY -StartupType Disabled"

# Habilita e inicia el SQLServerAgent
docker container exec $env:mssql_container_name powershell.exe /C "Set-Service sqlserveragent -StartupType Automatic"
docker container exec $env:mssql_container_name powershell.exe /C "Start-Service sqlserveragent"

# Resumen de los servicios después de la configuración
docker container exec $env:mssql_container_name powershell.exe /C "Get-Service *SQL* | Select-Object status, name, displayName, StartType"

Restaurar una copia de seguridad de una base de datos

Para ello vamos a ver como se organiza la estructura de directorios dentro de nuestro contenedor:

docker container exec bonisql powershell.exe /C "ls"
docker container exec bonisql powershell.exe /C "ls 'C:\Program Files\Microsoft SQL Server\'"
docker container exec bonisql powershell.exe /C "ls 'C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\'"
docker container exec bonisql powershell.exe /C "ls 'C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\Backup'"

Para copiar un archivo .bak a la ruta ..Backup del contenedor, usaremos el comando docker cp:

docker cp D:\SQLServer\Backups\WideWorldImporters-Full.bak bonisql:'C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\Backup'

Pero si nuestro contenedor está levantado, veremos el siguiente error:

docker : Error response from daemon: filesystem operations against a running Hyper-V container are not supported

Por lo tanto, sólo podemos copiar un fichero al contenedor si está detenido, hacemos lo siguiente:

docker container stop bonisql
docker cp D:\SQLServer\Backups\WideWorldImporters-Full.bak bonisql:'C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\Backup'
docker container start bonisql

Luego en nuestro cliente de SQL, conectados a la instancia del contenedor, podemos restaurar la base de datos como haríamos normalmente, por GUI o usando T-SQL:

USE [master];

-- Obtener nombres lógicos de los archivos dentro de la copia de seguridad (backup)
RESTORE FILELISTONLY 
	FROM DISK='C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\Backup\WideWorldImporters-Full.bak';

-- Escribir el comando, cambiando las rutas para la nueva ubicación
RESTORE DATABASE WideWorldImporters
	FROM DISK='C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\Backup\WideWorldImporters-Full.bak'
	WITH MOVE 'WWI_Primary' TO 'C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\Data\WideWorldImporters.mdf'
		, MOVE 'WWI_UserData' TO 'C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\Data\WideWorldImporters_UserData.ndf'
		, MOVE 'WWI_Log' TO 'C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\Data\WideWorldImporters.ldf'
		, MOVE 'WWI_InMemory_Data_1' TO 'C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\Data\WideWorldImporters_InMemory_Data_1'
		, STATS = 10;

Fácil, ¿verdad? 🙂 Análogamente, también podemos crear backups dentro del contenedor y copiarlos a nuestra máquina host.

Hacer que la base de datos persista

Hasta ahora todo lo que hemos hecho en el contenedor es efímero. Los contenedores inicialmente son stateless, útil para aplicaciones pero no para bases de datos. Surge así la necesidad de persistencia. La forma recomendada por Docker para conseguirla, es mediante el uso de volúmenes.

.\ps_container_creation_variables_mssql_advanced.ps1

docker run -e "ACCEPT_EULA=$env:mssql_container_eula" `
-e "SA_PASSWORD=$env:mssql_container_sa_passw" `
-e "MSSQL_AGENT_ENABLED=$env:mssql_container_agent" `
--volume=D:/SQLServer/Data/:C:/temp/ `
-e attach_dbs="[{'dbName':'persistida','dbFiles':['C:\\temp\\persistida_data.mdf','C:\\temp\\persistida_log.ldf']}]" `
--name $env:mssql_container_name `
--network $env:mssql_container_network `
--ip $env:mssql_container_ip `
-p $env:mssql_container_port `
-d $env:mssql_container_image

En este último bloque de código, vemos el uso los dos parámetros que necesitamos:

–volume : Aquí indicamos una ruta del host junto con una ruta dentro del contenedor (guest). Fíjate en el uso de “/”. Se establece un mapeo de rutas.

-e attach_dbs ; En este parámetro indicamos la ruta mapeada del contenedor. Observa que aquí se usa doble barra “\\”.

Comentar que antes de ejecutar el bloque anterior, debes colocar los ficheros de la base de datos (.mdf y .ldf) en la ruta del host que vamos a mapear.

La prueba final de creación del contenedor con todos los parámetros comentados (básicos, red, volumenes, etc) ha tardado sólo 59 segundos…

Ahora si quieres probarlo tú mismo, aquí tienes un enlace a todos los ejemplos usados y que completan esta guía.

Notas finales

Los contenedores de SQL Server en Windows son una excelente herramienta para desarrollar y/o probar nuestros cambios de base de datos. Cómo hemos visto, una vez que nuestro entorno está configurado, levantar un contenedor con un servicio de MSSQL es realmente rápido.

Esto es sólo la punta del iceberg, hay mucho más por aprender y probar, te invito a echar un vistazo a la documentación de Docker .

Espero haber sido de ayuda. ¡Hasta el próximo artículo!

Vientos de cambio

En los últimos 15 años ha surgido una cantidad considerable de nuevas tecnologías de base de datos. Los profesionales de la ingeniería del software, debemos familiarizarnos con ellas, ya que esto nos permitirá hacer una correcta elección ante determinados escenarios, permitiéndonos hacer uso de la herramienta más adecuada para superar nuevos desafíos.

Sigue leyendo

Cloud SQL en Google Cloud Platform

Recientemente he estado considerando la opción de Cloud SQL para SQL Server ofrecida por Google Cloud Platform (GCP). Esta es la plataforma de servicios en la nube ofrecida por el gigante Google. En terminos de servicios cloud, parece que aún no está al nivel de Amazon Web Services (AWS) o Microsoft Azure. Sin embargo, el crecimiento de GCP en los último años dos años ha sido significativo. Sigue leyendo

Creando nuestro laboratorio de Elasticsearch con Hyper-V

Para crear nuestro laboratorio de Elasticsearch en un equipo Windows, con el que poder experimentar más adelante 😊, una buena opción es usando Hyper-V. Este es un software de virtualización que ofrece Microsoft y que se puede instalar en varias versiones de Windows 10 de forma gratuita.

Objetivo

Vamos a crear un cluster con las siguientes características:

  • Nombre del cluster: es-cluster-lab
  • Número de nodos: 3
  • Nombre de los nodos: elasticsearch-lab-{1..3}.localdomain

Sigue leyendo

Query Store: Ejemplos prácticos

En mi primer artículo sobre Query Store, hace ya bastante tiempo, comenté que escribiría otro incluyendo ejemplos de configuraciones, monitorización y consumo de recursos. Bien, ese día ha llegado!

Código de ejemplo de configuración

USE master;
GO

ALTER DATABASE [NombreDeTuDB]
	SET QUERY_STORE = ON
	(
		OPERATION_MODE = READ_WRITE
		, CLEANUP_POLICY = (STALE_QUERY_THRESHOLD_DAYS = 14)
		, DATA_FLUSH_INTERVAL_SECONDS = 600
		, INTERVAL_LENGTH_MINUTES = 10
		, MAX_STORAGE_SIZE_MB = 512
		, QUERY_CAPTURE_MODE = AUTO
		, SIZE_BASED_CLEANUP_MODE = AUTO
		, MAX_PLANS_PER_QUERY = 7
	);

Puedes ver que los parámetros se explican en el citado artículo. Como siempre, te recomiendo probar bien la configuración en entornos de pre-producción, ya que la carga de trabajo de tu Base de Datos influye de forma directa. Dicho esto, este ejemplo de configuración es funcional y no he tenido problemas con ello.

Código de ejemplo para monitorizar el uso de disco de Query Store

Este código lo vamos a desglosar por pasos:
1) Creamos una base de datos (opcional) y una nueva tabla para guardar los datos que vamos a monitorizar:

USE master;
GO

CREATE DATABASE DBA_Admin;
GO

USE DBA_Admin;
GO

CREATE TABLE dbo.QueryStoreSizeHistory (
	current_storage_size_mb	BIGINT NOT NULL
	, max_storage_size_mb	BIGINT NOT NULL
	, date_time				DATETIME2(2) DEFAULT(GETDATE()) NOT NULL
);

2) A continuación podemos crear un SQL Agent Job, que se lance cada N horas, y que  sólo va a ejecutar el siguiente código de T-SQL:

USE DBA_Admin;
GO
INSERT INTO dbo.QueryStoreSizeHistory (
current_storage_size_mb
, max_storage_size_mb
)
SELECT current_storage_size_mb
, max_storage_size_mb
FROM MiDB.sys.database_query_store_options;

Fíjate que la vista del sistema sys.database_query_store_options existe a nivel de la Base de datos donde QS está configurado. Por lo que hace falta usar la referencia en tres partes (NombreDB.NombreEsquema.NombreTabla).

3) Finalmente tras dejar pasar un tiempo, puedes comprobar como se ha ido usando el espacio asignado a Query Store:

SELECT *
	FROM DBA_Admin.dbo.QueryStoreSizeHistory
	ORDER BY date_time;

Mencionar que esta tabla de monitorización no tiene índices de ningún tipo ni PK. Esto es así poque su tamaño no debería superar unos pocos MBytes. Está pensanda para una comprobación inicial sobre cómo de rápido se llena el espacio de QStore. Si quieres mantener esta monitorización de forma indefinida, mi recomendación sería incluir un paso de limpieza/borrado de los registros más antiguos.

Tras un tiempo, con QS en funcionamiento, deberías echar un vistazo a los informes en tu Base de Datos a través de la interfaz de SQL Server Management Studio (SSMS):

2019-04-26_00h56_29

Lo recomendable en este punto, es que lo pruebes y veas por ti mismo lo útil que puede llegar a ser. Puedes usar también los ejemplos que utilicé en mi última presentación sobre Query Store , mira el link en la sección de comentarios.

Aparte de los informes predefinidos de SSMS, te recomiendo echar un vistazo a las consultas del sistema que vienen como parte de Query Store, y que te brinda toda la personalización que se te ocurra en tus comprobaciones. En la documentación de MSSQL puedes encontrar un buen puñado de ejemplos que usan esas vistas del sistema. Resultan especialmente interesantes las consultas bajo la sección Performance Auditing and Troubleshooting.

Y eso es todo por hoy, espero que te haya sido de ayuda. Cualquier pregunta, puedes enviarme un mensaje o dejar un comentario.

¡Hasta el próximo artículo!

Grupo de Usuarios SQL Server Málaga: ¡Tres años ya!

El 9 de Febrero de 2016 un grupo de amigos se reunió para tomar unas cervezas y hablar sobre SQL Server fuera del trabajo… Y surgió una pregunta ¿Por qué no crear una comunidad de usuarios en Málaga?

highres_467945864

Se acaban de cumplir 3 años desde que aquel día, y hemos compartido muchos buenos momentos, aprendido muchísimo, conocido otros grandes profesionales e interesantes empresas. Hemos mantenido un ritmo casi constante de una sesión técnica cada 2 meses, siempre abierta, de forma gratuita y dando la bienvenida a toda persona interesada en nuestros temas.

Sin olvidar que también tenemos un grupo en PASS, una comunidad global (también abierta) de SQL Server, dónde puedes encontrar una cantidad ingente de información de muy buena calidad. A fin y al cabo esa es nuestra principal motivación: Compartir conocimiento.

Así ha sido y así seguirá siendo, y que nuestra comunidad siga creciendo,  y es que a día de hoy superamos los 500 miembros en Meetup… Muchas gracias a todos los que formáis parte de esta familia geek que tenemos en Málaga. Especial mención para Carlos, David y Jesús, y a los amigos que habéis llegado posteriormente.

¡GRACIAS a tod@s!

Una opción a considerar en nuestras tablas: Large Value Types Out Of Row

Hoy vamos a comentar una opción que aunque existe desde hace varios años, es desconocida por muchos: “Large Value Types Out Of Row”.

¿Qué nos ofrece? Imagina una tabla con varias columnas y algunas de ellas de tipo grande (VARCHAR(MAX), NVARCHAR(MAX), XML, TEXT, VARBINARY, etc). La tabla requerirá muchas más páginas (disco) para almacenar la información, que si no tuviera esas columnas. Bien, con esta opción habilitada (y algo de trabajo adicional si la tabla ya tiene datos) podemos hacer que las consultas y operaciones DML con esta tabla sean significativamente más rápidas, además de otros beneficios.

¿Cómo es posible? Tras habilitar esta opción, las columnas de tipo grande pasan a almacenarse en páginas separadas. En una tabla que ya existe con miles de registros, esto puede implicar una liberación de espacio significativa en las páginas que usaba la tabla inicialmente. Dependerá de cuanta información de tipo grande existe. En una consulta que utiliza scans como la del ejemplo más abajo, vamos a ver cómo se reduce el número de páginas cuando se ejecuta la consulta. Esto significa que la consulta va a ser más rápida y consumirá menos recursos: Memoria y CPU.

La opción se habilita a nivel de tabla y la sintaxis es bastante sencilla:

USE AdventureWorks2014; -- Cambiar por tu nombre de BBDD
GO

EXEC sp_tableoption 'Person.Person', 'large value types out of row', 1;

En el siguiente ejemplo donde puedes, ejecutando paso a paso, cómo afecta positivamente esta opción al número de lectura lógicas cuando hacemos una consulta en la tabla modificada.

-- Limpiamos la cache para hacer pruebas sin nada precargado en memoria
DBCC DROPCLEANBUFFERS;
DBCC FREEPROCCACHE;
GO
USE AdventureWorks2014;
GO

-- 1) Comprobamos las estadísticas de acceso a disco para la siguiente consulta, esta tabla tiene la opción large_value_types_out_of_row desactivada(valor por defecto)
SET STATISTICS IO, TIME ON;
GO

SELECT FirstName
, MiddleName
, LastName
, ModifiedDate
FROM Person.Person;

SET STATISTICS IO, TIME OFF;
GO
-- RESULTADO:
--		(19972 rows affected)
--		Table 'Person'. Scan count 1, logical reads 3847, physical reads 3, read-ahead reads 3976, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
--		(1 row affected)
--		SQL Server Execution Times:
--		CPU time = 47 ms,  elapsed time = 1055 ms.

-- 2) Cambiamos la opción large_value_types_out_of_row en la tabla
EXEC sp_tableoption 'Person.Person', 'large value types out of row', 1; -- switch on the feature
GO

-- 3) El cambio de esta opción no toma efecto para los valores existentes hasta el momento en que se actualicen
UPDATE Person.Person
SET AdditionalContactInfo = AdditionalContactInfo
WHERE AdditionalContactInfo IS NOT NULL;

UPDATE Person.Person
SET Demographics = Demographics
WHERE Demographics IS NOT NULL;

-- Reconstruimos todos los índices para qué las páginas que lo componen se reordenen, ojo esta operación puede ser costosa y generar bloqueos
ALTER INDEX ALL ON Person.Person REBUILD;

-- Limpiamos la cache de nuevo para comparar el efecto de la nueva config.
DBCC DROPCLEANBUFFERS;
DBCC FREEPROCCACHE;

-- 4) Comprobar de nuevo las estadísticas de acceso a disco, como en el paso 1)
SET STATISTICS IO, TIME ON;
GO

SELECT FirstName
, MiddleName
, LastName
, ModifiedDate
--, AdditionalContactInfo
FROM Person.Person;

SET STATISTICS IO, TIME OFF;
GO
-- RESULTADO:
--		(19972 rows affected)
--		Table 'Person'. Scan count 1, logical reads 268, physical reads 0, read-ahead reads 220, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
--		(1 row affected)
--		SQL Server Execution Times:
--		CPU time = 15 ms,  elapsed time = 241 ms.

Observa que la cantidad de lecturas lógicas pasa de 3800 a menos de 300. Esto es una reducción del 90% para este escenario. En todas las tablas no va a pasar lo mismo, ya que depende principalmente de los datos que haya en la tabla, y de la consulta en sí.

Necesitarás la Base de datos de AdventureWorks2014, puedes descargarla en este enlance. El script anterior también está disponible en GitHub.

Si quieres comprobar cuantas tablas pueden beneficiarse de esta opción en tus bases de datos, puedes usar esta consulta que he subido a la TechNet Gallery. No olvides dar tu valoración! 🙂 Si quieres ver más aquí tienes un link a la documentación oficial.

Si lo piensas, esto es equivalente a hacer un particionado vertical de una tabla, sacando las columnas grandes a una tabla nueva. Lo interesante de la opción “Large Value Types Out Of Row” es que es completamente transparente para la aplicación, y mucho más sencillo de implementar.

Si lo probáis, comentadme que tal os parece y los resultados.

Hasta el próximo artículo!