4
GPI.- Confidencial Tel: (506) 297 8132 – 244-5849 | De la Basílica de Santo Domingo, Heredia; 200 mts norte y 900 mts este. Apto 103-1100, Costa Rica En este artículo analizaremos el comportamiento de las bases de datos cuando se le realizan operaciones de Shrink. Algunos DBA’s realizan esta tarea de manera común sin percatarse talves del grave daño que le están causando a la base de datos. Este ejemplo lo tome de la explicación realizada por Paul Randal durante una conferencia en SQL Server Connections y otros métodos de ingreso de datos proporcionados por Itzik Ben Gan. Lo que haremos es crear una pequeña base de datos de prueba, la vamos a llenar con una serie de datos de forma aleatoria, luego borramos la tabla de parámetros y realizamos el shrink para ver los resultados finales. USE MASTER; GO IF DATABASEPROPERTYEX ('shrinkdb', 'Version') > 0 DROP DATABASE shrinkdb; Create database ShrinkDb; Go --Creamos luego una tabla llamada empleados USE [Shrinkdb] GO -- Creamos una tabla auxiliar que va a servirnos para llenar datos aleatorios SET NOCOUNT ON; IF OBJECT_ID('dbo.Nums') IS NOT NULL DROP TABLE dbo.Nums; CREATE TABLE dbo.Nums(n INT NOT NULL PRIMARY KEY); DECLARE @max AS INT, @rc AS INT; SET @max = 1000000; SET @rc = 1; INSERT INTO dbo.Nums(n) VALUES(1); WHILE @rc * 2 <= @max BEGIN INSERT INTO dbo.Nums(n) SELECT n + @rc FROM dbo.Nums; SET @rc = @rc * 2; END INSERT INTO dbo.Nums(n) SELECT n + @rc FROM dbo.Nums WHERE n + @rc <= @max; GO -- Parámetros de configuración para cargas posteriores DECLARE @numorders AS INT, @numcusts AS INT, @numemps AS INT, @numshippers AS INT, @numyears AS INT,

Sql tips 03_shrink

Embed Size (px)

Citation preview

Page 1: Sql tips 03_shrink

GPI.- Confidencial

Tel: (506) 297 8132 – 244-5849 | De la Basílica de Santo Domingo, Heredia; 200 mts norte y 900 mts este. Apto 103-1100, Costa Rica

En este artículo analizaremos el comportamiento de las bases de datos cuando se le realizan

operaciones de Shrink. Algunos DBA’s realizan esta tarea de manera común sin percatarse

talves del grave daño que le están causando a la base de datos. Este ejemplo lo tome de la

explicación realizada por Paul Randal durante una conferencia en SQL Server Connections y

otros métodos de ingreso de datos proporcionados por Itzik Ben Gan.

Lo que haremos es crear una pequeña base de datos de prueba, la vamos a llenar con una serie

de datos de forma aleatoria, luego borramos la tabla de parámetros y realizamos el shrink para

ver los resultados finales.

USE MASTER;

GO

IF DATABASEPROPERTYEX ('shrinkdb', 'Version') > 0

DROP DATABASE shrinkdb;

Create database ShrinkDb;

Go

--Creamos luego una tabla llamada empleados

USE [Shrinkdb]

GO

-- Creamos una tabla auxiliar que va a servirnos para llenar datos aleatorios

SET NOCOUNT ON;

IF OBJECT_ID('dbo.Nums') IS NOT NULL

DROP TABLE dbo.Nums;

CREATE TABLE dbo.Nums(n INT NOT NULL PRIMARY KEY);

DECLARE @max AS INT, @rc AS INT;

SET @max = 1000000;

SET @rc = 1;

INSERT INTO dbo.Nums(n) VALUES(1);

WHILE @rc * 2 <= @max

BEGIN

INSERT INTO dbo.Nums(n) SELECT n + @rc FROM dbo.Nums;

SET @rc = @rc * 2;

END

INSERT INTO dbo.Nums(n)

SELECT n + @rc FROM dbo.Nums WHERE n + @rc <= @max;

GO

-- Parámetros de configuración para cargas posteriores

DECLARE

@numorders AS INT,

@numcusts AS INT,

@numemps AS INT,

@numshippers AS INT,

@numyears AS INT,

Page 2: Sql tips 03_shrink

GPI.- Confidencial

Tel: (506) 297 8132 – 244-5849 | De la Basílica de Santo Domingo, Heredia; 200 mts norte y 900 mts este. Apto 103-1100, Costa Rica

@startdate AS DATETIME;

SELECT

@numorders = 1000000,

@numcusts = 20000,

@numemps = 3500,

@numshippers = 5,

@numyears = 4,

@startdate = '20050101';

-- Creamos y llenamos la tabla de empleados con un maximo de 3500 empleados,

las variables de arriba permiten cambiar dichos parámetros

CREATE TABLE dbo.Empleados

(

empid INT NOT NULL,

Apellido NVARCHAR(25) NOT NULL,

Nombre NVARCHAR(25) NOT NULL

CONSTRAINT PK_empleados PRIMARY KEY(empid)

);

INSERT INTO dbo.Empleados(empid, Apellido, Nombre)

SELECT n AS empid,

N'Apellido_' + CAST(n AS NVARCHAR(10)) AS Apellido,

N'Nombre_' + CAST(n AS NVARCHAR(10)) AS Nombre

FROM dbo.Nums

WHERE n <= @numemps;

CREATE NONCLUSTERED INDEX INX_APE ON EMPLEADOS (APELLIDO)

/*

Aca podemos chequear los datos de la tabla para que revisen los datos

cargados

*/

SELECT * FROM Empleados

--Chequeamos el porcentaje de fragmentación de la tabla para medir como se

encuentra el índice.

SELECT avg_fragmentation_in_percent, fragment_count FROM

sys.dm_db_index_physical_stats (

DB_ID ('shrinkdb'), OBJECT_ID ('empleados'), 1, NULL, 'LIMITED');

GO

Page 3: Sql tips 03_shrink

GPI.- Confidencial

Tel: (506) 297 8132 – 244-5849 | De la Basílica de Santo Domingo, Heredia; 200 mts norte y 900 mts este. Apto 103-1100, Costa Rica

--Como podemos ver el índice no muestra fragmentación considerable. Este debe

de ser el comportamiento normal

-- Ahora borramos la tabla NUMS que utilizamos como utilitario previamente

DROP TABLE nums;

GO

-- hacemos el shrink de la base de datos para "recuperar" espacio en disco

DBCC SHRINKDATABASE (shrinkdb);

GO

-- Chequeamos la fragmentación nuevamente

SELECT avg_fragmentation_in_percent, fragment_count FROM

sys.dm_db_index_physical_stats (

DB_ID ('shrinkdb'), OBJECT_ID ('empleados'), 1, NULL, 'LIMITED');

GO

/*

Ahora como pueden ver, resulta ser que el indice esta totalmente fragmentado,

y esto se debe a que

el Shrink inicia el proceso desde el final del archivo de datos hacia el

inicio, lo que hace que el orden

Page 4: Sql tips 03_shrink

GPI.- Confidencial

Tel: (506) 297 8132 – 244-5849 | De la Basílica de Santo Domingo, Heredia; 200 mts norte y 900 mts este. Apto 103-1100, Costa Rica

de las paginas cambie y se fragmente. Y esto q provoca? Rendimiento pésimo de

la base de datos, encolamiento en

discos, mayor consumo de recursos en general... asi que acá les dejo la

inquietud y cuando algún DBA les

diga que va a hacer un shrink en Producción... YA SABEN Q HACER... :)

*/