Habitualmente se piensa que el resultado positivo de un índice sólo se traduce en una lectura más rápida de datos. En esta entrada demostraré que también nos ayudan a reducir el uso de memoria al cargar menos páginas en el buffer de SQL Server.
Recordemos que SQL Server coloca en memoria los datos antes de poder despacharlos, esto se hace de esa forma para que la futura lectura de los datos sea mucho más rápida y no tenga que ir hasta los dispositivos de almacenamiento para recuperar la información.
Quiero hacer un ejercicio muy sencillo pero significativo con la base de datos AdventureWorks. El objetivo es obtener el total de ventas de los productos de color rojo. Analizaremos la cantidad de páginas que se cargan en memoria para poder despachar el resultado.
Nuestro query queda de la siguiente manera:
SELECT SUM(SOD.LineTotal) AS Total
FROM Sales.SalesOrderDetail SOD
INNER JOIN Production.Product P
ON SOD.ProductID = P.ProductID
WHERE P.Color = 'Red'
Para obtener la cantidad de páginas que está utilizando nuestra base de datos AdventureWorks en memoria, podemos conectarnos a ella y ejecutar el siguiente query:
SELECT COUNT(*) AS paginas_usadas
FROM sys.dm_os_buffer_descriptors
WHERE database_id = DB_ID()
Comenzaremos limpiando la memoria y verificando que no se estén usando páginas por parte de la base de datos AdventureWorks:
USE AdventureWorks
GO
CHECKPOINT
DBCC DROPCLEANBUFFERS
GO
SELECT COUNT(*) AS paginas_usadas
FROM sys.dm_os_buffer_descriptors
WHERE database_id = DB_ID()
Vamos a ejecutar el query que obtiene el total de ventas de los productos de color rojo y verificamos de nueva cuenta la cantidad de páginas utilizadas por la base de
datos AdventureWorks:
SELECT SUM(SOD.LineTotal) AS Total
FROM Sales.SalesOrderDetail SOD
INNER JOIN Production.Product P
ON SOD.ProductID = P.ProductID
WHERE P.Color = 'Red'
GO
SELECT COUNT(*) AS paginas_usadas
FROM sys.dm_os_buffer_descriptors
WHERE database_id = DB_ID()
En mi caso la cantidad de páginas usadas es de 772
Ahora vamos a crear un índice que nos ayude a optimizar el query, éste será creado sobre la columna ProductID e incluirá las columnas UnitPrice, UnitPriceDiscount y OrderQty
las cuales son utilizadas para calcular LineTotal. Nuestro código queda de la siguiente manera:
CREATE INDEX ixSProductID
ON Sales.SalesOrderDetail (ProductId)
INCLUDE (UnitPrice, UnitPriceDiscount, OrderQty)
Volvemos a limpiar la memoria, ejecutamos nuestro query y verificamos la cantidad de páginas utilizadas por la base de datos AdventureWorks:
CHECKPOINT
DBCC DROPCLEANBUFFERS
GO
SELECT SUM(SOD.LineTotal) AS Total
FROM Sales.SalesOrderDetail SOD
INNER JOIN Production.Product P
ON SOD.ProductID = P.ProductID
WHERE P.Color = 'Red'
GO
SELECT COUNT(*) AS paginas_usadas
FROM sys.dm_os_buffer_descriptors
WHERE database_id = DB_ID()
En mi caso la cantidad de páginas usadas es de 251
Notemos que la memoria necesaria para despachar el query se redujo en un 67.48%. ¿Qué debemos notar?, que los índices no sólo reducen el tiempo que tarda un query en ejecutarse sino también la cantidad de páginas que SQL Server necesita colocar en memoria para despachar el resultado.
Espero les haya resultado de utilidad esta entrada, nos vemos en la siguente.
No hay comentarios.:
Publicar un comentario