Creando una dimensión tiempo en Analisys Services 2/2

Posted by Miguel Egea | Posted in Analisys Services | Posted on 23-01-2010

2

En el artículo anterior de la serie vimos omo  crear la primera parte de la dimensión tiempo. En este momento tenemos ya constrido nuestro DataSource View y vamos a ver como se construye nuestra dimensión tiempo desde el punto de vista de Analisys Services. Para ello empezamos con nuestro BIDS (Bussiness Intelligence Development Studio) abierto con el proyecto tal y como lo teníamos al final del artículo anterior.

Cabe destacar que estamos haciendo este proyecto con SQL Server 2008, cambia algo con respecto de 2005, así que no es de extrañar que los menús no sean exactamente los mismos, aunque si que lo es el concepto y la forma de hacerlo.

Para comenzar pulsaremos sobre el apartado dimensiones con el botón derecho, eligiendo la opción Nueva dimensión, en ese instante nos aparecerá el asistente para la creación de dimensiones, y tras saltarnos si procede la página de bienvenida, elegiremos la opción “Use an existing table”, Usar una tabla existente. (Aunque hay opciones para crear una tabla de tiempo en el origen de datos o en el servidor, y que estas opciones puedan resultar muy atractivas a simple vista, nosotros vamos a usar la forma máal de  crear todo lo relacionado con la dimensión tiempo, porque nuestro objetivo es entenderlo. Además, al menos yo, siempre uso el mecanísmo que estoy describiendo, porque no me aporta un trabajo extra y si me da un control muy importante sobre como funciona la dimensión tiempo.

Â

En el siguiente paso del asistente tenemos que seleccionar en que objeto del Data Source View nos basamos para crear la dimensión, adicionalmente hay que decir cual es la clave primaria de ese objeto (en nuestro caso es fácil, puesto que la infiere del model) y que columna contiene el descriptor de esa clave (name column). Elegiremos el campo Fecha como name column mientras mantenemos FechaKey como la clave primaria de esta dimensión.

En el siguiente paso del asistente es cuando realmente tenemos que definir que estamos hablando de una dimensión de tipo tiempo. Esto cambia con respecto a 2005, en el que había un wizard que nos preguntaba directamente cual era el campo que contenía el dato para mes, semana, dia, trimestre, etc.. En el asistente aparece un campo para definir el tipo de atributo, y es ahí donde concretamos cual es la naturaleza de cada uno de los campos,  por ejemplo, en la siguiente figura podemos ver como hemos especificado para Fecha Key que se trata de un atributo de tipo date, es decir, es la fecha propiamente dicha. También aprovecharemos este paso para ajustar los nombres que no acaben de gustarnos, (por ejemplo quitaré Fecha Key y lo traduciré por fecha.

Una vez que hemos elegido todos los atributos podemos continuar con el asistente, en la imagen que teneis a continuación podeis ver como he hecho los siguiente cambios:

  • He renombrado Fecha Key por fecha y Mes Key por mes
  • He especificado que el tipo de atributo es Date para la fecha
  • Year para el año
  • Month para el mes
  • Week para la semana
  • Day Of year para el dia del año
  • Day of Month para el dia del mes
  • Day of Week para el dia de la semana

Despues de esto simplemente se termina el asistente en el que nos dice que va  crear la dimensión tiempo como puede verse a continuación.

Esta dimensión tiempo, ya funcionaría, pero no es aún ni demasiado navegable (no tiene jerarquías) ni mucho menos optima, porque las relaciones entre atributos tampoco están especificadas. Esto si es un cambio importante en SQL Server 2008, la relación entre atributos cuenta ahora con una pestaña específica, que lo hace más visual. El estado inicial de estas relaciones entre atributos es el que puede verse en la figura a continuación.

Sin embargo, debemos especificar las relaciones reales de dependencia, ya que esas relaciones ayudarán mucho al rendimiento, debido a que con estas relaciones establecidas, SQL Server Analisys Services puede inferir, que el resultado de un mes, es el resultado de sumar los dias (para operaciones aditivas). mientras que el resultado del año es el resultado de sumar los meses. Si estas relaciones no son especificadas, esas conclusiones no pueden establecerse y por tanto se hace un uso suboptimo de los datos. En el grafico siguiente puede verse como establecemos estas relaciones de dependencia de forma adecuada.

Una parte importante, en la que muchas veces no nos fijamos es en el color de las flechitas del apartado Attibute Relasionships, el color más gris indica que la relación que existe entre esos atributos es una relación flexible, es decir que puede cambiar con el tiempo, por ejemplo en el caso del jefe del que depende una persona, es claro que puede cambiar con el tiempo, aunque sea una relación clara entre los atributos, sin embargo, en nuestro caso,  la relación Fecha->Mes y la Relación Mes-Año, están especificada como relaciones rígidas que quiere decir que el mes 2009-01 siempre será del año 2009 y eso no va a cambiar (cosa que es bastante obvia).

Una vez que tenemos establecidas las relaciones solo nos falta añadirle a la dimensión las jerarquias que nos sirvan para especificar el criterio por el que queremos que se navegue nuestra dimensión. Para ello simplemente arrastraré los atributos hasta el apartado de jerarquías. Adicionalmente voy a ocultar el atributo año, para no confundir a los usuarios, si lo dejo podrán llegar al año desde la jerarquia y desde el atributo, y en mi experiencia eso lia bastante a los usuarios. En la imagen siguiente podeis ver como quedan mis jerarquías.

Podeis observar que no tengo ningún warning ni ninguna flechita azul, esto es simplemente porque he seguido todos los patrones de buen diseño que SQL Server 2008 Analisys Services tiene especificados para una dimensión como esta. Ahora simplemente vamos a ver un ejemplo de como navegarla, lo teneis en el siguiente gráfico.

Por último, aunque esta serie de dos artículos acaba, en posteriores post, intentaré hablar de como localizar esta dimensión, especificando que para usuarios en inglés el nombre le aparezca en inglés, mientras que para usuarios en castellano los nombres aparezcan en castellano, esto es January para los Ingleses, Enero para los hispanos.
Esto será en otro post.
Saludos Cordiales

Mis compañeros de relacional migran una BBDD 24×7 con 4 segundos de tiempo de caida!

Posted by Miguel Egea | Posted in Noticias | Posted on 20-01-2010

0

El equipo de mi amigo eladio, unos cracks. mas informacion

SQL Server 2008, tips an tricks. Miguel Egea Charla en video en el CodeCamp 2009

Posted by Miguel Egea | Posted in Relacional | Posted on 18-01-2010

0

SQL Server 2008 incorpora nuevas funcionalidades para dar soporte a las tecnologías que demanda la sociedad; en esta linea, veremos cómo SQL Server hace la vida más fácil gestionando localizaciones geográficas y puntos en el espacio; además veremos cómo SQL Server nos ayuda a gestionar más eficientemente videos, documentos, y archivos de gran tamaño.

Mi charla sobre Analisys Services 2008 en el Codecamp de tarragona

Posted by Miguel Egea | Posted in Analisys Services | Posted on 18-01-2010

4

Me parece increible que yo diese esta charla y no saber que estaba grabada y publicada, gracias a mi amgigo Salvador Ramos y a un portal de bussiness intelligence me he enterado que estaba publicado. Yo no se dar una charla serio, los que me conoceis ya sabeis como soy, para los demás pues bueno, ya podeis verme y oirme.

Creando una dimensión Tiempo en Analisys Services 1/2

Posted by Miguel Egea | Posted in Analisys Services | Posted on 17-01-2010

2

PortalSQL tradicionalmente venía hablando solo de motor relacional, sin embargo, mi carrera me ha llevado a la parte multidimensional, y os prometo que ha sido un descubrimiento total, trabajar con cientos o miles de millones de filas, y que los usuarios vean los resultados en tiempo real es una experiencia increible. Si además le podemos añadir luego cierta lógica relacionada con el tiempo y fórmulas que añadan valor a las operaciones, los proyectos sin duda tienen tendencia a ser más exitosos.

Dicho esto, vamos a comenzar con el primer artículo sobre Analisys Services, pasaremos casi de largo por algunos pasos básicos, y construiremos la dimensión tiempo paso a paso para que los veais.

Comenzamos en el resultado de los artículos sobre la dimensión tiempo, es decir nuestro datawarehouse cargado y relleno con la dimensión tiempo en Español, Inglés y frances como pude verse en la siguiente figura.

Ahora lo que vamos a hacer es abrir el Bussiness Studio Development Studio desde el menú tal y como puede verse en la siguiente figura.

Después lo que haremos será crear un proyecto de Analisys services llamado Dimensión Tiempo, para ello en Fichero –> Nuevo –>Proyecto–> Bussiness Intelligence Projects y ahí elegimos analisys services projects, tal y como podeis ver en la siguiente figura.

Una vez creado el proyecto nos aparecerán los distintos apartados de Analisys Services, los que necesita para crear el proyecto. Lo primero que haremos será crear el Data Source, es decir, crear una conexión al motor relacional en el que estará la tabla tiempo en la que nos vamos a basar, en realidad, lo que hacemos es muy parecido a lo que se hacía cuando se creaba una conexión ODBC, es decir crear una conexión a una base de datos (no tiene por que ser SQL Server, puede ser cualquier otro motor).
Importante Pensad que estamos haciendo un proyecto que al final no es mas que código fuente que se ejecutará en un servidor, por tanto, la conexión que creamos al final se conectará no desde nuestra máquina, no con nosotros logueados, sino desde el servidor, y ejecutado bajo las credenciales que levanten el servicio de Analisys Services.

Para crear el Data Source pulsaremos con el botón derecho sobre la carpeta Data Sources, y elegiremos New Data Source :

A partir de elegir la opción nuevo data source nos aparece un asistente para crear la conexión, saltamos el primer paso, que es siempre el de bienvenida, y en el segundo nos permite elegir alguna conexión que ya hayamos hecho anteriormente o podemos pulsar el botón nueva conexión.

Una vez pulsado el botón nueva conexión nos va a aparecer la siguiente pantalla, en la que realmente será la que creemos la conexión.

En la parte superior de la imagen podeis ver como hay una lista desplegable en la que seleccionamos el proveedor de datos que usaremos para conectarnos, en nuestro caso es SQL Server, de forma que hemos elegido el Native Client 10.0, basta con que tengas instalados los drivers adecuados para poder elegir cualquier conexión a cualquier base de datos del mercado.

El siguiente paso, que es el penúltimo, nos pide la información de impersonación, es decir, nos ayuda a decir con que credenciales ha de conectarse el servicio de Analisys Services a esta base de datos, podemos especificar unas credenciales de windows, podemos especificar que se conecte bajo las credenciales del servicio, que se usen nuestras credenciales, o que no use ninguna.


El último paso es especificar el nombre que daremos a la conexión, elegid cualquiera que nos vale.

Una vez creado el Data Source, (Origen de Datos), debemos crear el Data Source View, esto nos permite seleccionar bien tablas o vistas, o bien crear consultas y que aparezcan en nuestro modelo como una tabla. Para nuestro ejemplo, en el que no vamos a hacer un cubo completo sino solamente la dimensión tiempo, nos valdrá con la tabla que tiene la dimensión tiempo. Realmente es la única que vamos a necesitar, pero en futuros artículos espero que creemos un cubo completo contra Adventure Works por ejemplo, para que veais el proceso completo.

Para crear el data source view, sobre el apartado en el explorardor de soluciones, botón derecho, nuevo data source view y seguimos el asistente, en el primer paso solamente es el de bienvenida, el segundo nos ofrece para elegir el datasource del que saldrá la conexión, obviamente elegiremos el que acabamos de crear.

Las alternativas que nos ofrece el asistente en el segundo paso son las que usará para inferir claves primarias, y relaciones en las tablas seleccionadas. El data source view añade esta lógica sin modificar el origen de datos, es decir, él necesita saber que campos son clave primaria y como se relacionan las tablas para ayudarnos en la creación de las dimensiones y hechos posteriormente. La alternativa que elijais dependerá mucho de como tengais vuestro protocolo de nombres en la creación, fijaos en los ejemplos que pone cuando pinchais una de las alternativas y elegid el más adecuado a vuestro esquema. En el siguiente paso hay que elegir que tablas nos traemos. En nuestro caso solo Dimensiones.Tiempo, fijaos que hay una parte de filtro abajo de las tablas de origen, esto es porque en los esquemas grandes suelen haber, cientos, quizás miles de tablas (el otro día vi un ejemplo de un sistema navision con 90.000 tablas…) para elegir una en concreto ayudarnos del filtro será fundamental en estos casos.

Fijaos también en el botón Add Related tables, en los que el sistema va a traerse las tablas que estén relacionadas, averiguando esto a través de las restricciones de integridad referencial. De esta forma podemos elegir el conjunto de tablas que necesitamos de una forma mucho más sencilla.

Hasta aquí la primera parte, en breve publicaré el final de la creación de la dimensión tiempo, lo que es la creación en sí.

Saludos

Usando vistas para crear subconjuntos de datos

Posted by Miguel Egea | Posted in Relacional | Posted on 16-01-2010

0

La verdad es que he usado esta técinca bastante, lo que hago es crear vistas, en una base de datos que apunten a las tablas o vistas originales en la otra base de datos. De esta forma no se duplica el espacio, y además no se penaliza (apenas) el rendimiento, en principio la única operación adicional que hace el motor frente a que estén en la misma base de datos es comprobar que el usuario tenga permisos en la otra base de datos. En resumen, no es malo crear una vista en una base de datos apuntando a otra en el mismo server, las operaciones CRUD (Inserción, lectura, actualización y borrado) segurian funcionando todas como si de una tabla se tratase.

Sin embargo si quieres crear un gran número de vistas, la cosa puede ser tediosa. Si sé que por ejemplo voy a crear vistas para todas las tablas de un esquema, o para todas las que cumplen ciertos patrones, puedo utilizar otra técnica que exploto de vez en cuando, crear una consulta que me devuelva las consultas a ejecutar, para despues de esto copiar y pegar.

Si las operaciones a hacer son CRUD, no hay problema separandolas con ; todo funciona perfectamente, sin embargo si las operaciones a realizar son operaciones de definición de objetos (sentencias DDL), entonces hay que sepaararlas por GO para ejecutarlas en el entorno, o bien, hay que ejecutarlas una a una, esto, tampoco es algo que yo desee. ¿como hago para añadir los GO?. Las técnicas que uso habitualmente son dos una añadir al final de la sentencia el caracter 13 y el caracter 10 . Algo así

select 'select 1 ' +char(10) +CHAR(13) + 'go'

Sin embargo este código no funciona en el modo Grid, habitual de management estudio, si copiamos desde el grid el código y lo pegamos, nos aparecerá en una sola línea y no en dos, que es lo que buscamo,s así pues hemos de pasara a modo texto (pulsando CTRL+to bien en el menú Query->Results To->Text. La verdad es que queda algo “chapuza” esta alternativa.

¿alguna otra solución? Pues lo que tendríamos que hacer es además de construir la sentencia, añadir tantos “GO” como sentencias haya… eso es sencillo, si la primera linea es :

select  'CREATE VIEW ' + TABLE_SCHEMA+'.['+TABLE_NAME  +  '] AS select * from vdnav60.'+table_schema+'.['+table_name+'];'  from information_Schema.tables where table_name like '%patron%'

Lo que hemos de hacer es un select, pero esta vez solo con el literal “GO” del mismo origen, de esta forma tendremos el mismo número de “go”. Sería algo así

select  'GO'  from information_Schema.tables where table_name like '%patron%'

El problema aquí viene por dos partes, la primera, las dos sentencias no son una sola, que es lo que yo necesito, (sin embargo ambas solo devuelven una columna, que es un literal con lo que sirve como código). Esto podemos solucionarlo usando una cláusula UNION ALL (al ser la estrutura devuelta igual).

Pero esto aún encierra un problema adicional, que es que no vienen en el orden adecuado, para ordenar algo podemos usar la cláusula order by, pero no tenemos ningún campo que nos sirva para hacer ese entrelazado (o al menos no podemos suponer que lo tenemos), es por ello que yo uso este otro script.

select  'CREATE VIEW ' + TABLE_SCHEMA+'.['+TABLE_NAME  +  '] AS select * from vdnav60.'+table_schema+'.['+table_name+'];'  from information_Schema.tables where table_name like '%patron%'
union all
select row_number() over( order by table_name), 'go' from vdnav60.information_Schema.tables where table_name like '%patron%'

Las cláusulas Row_number() nos van a devolver el número de fila según los criterios que usemos (partition by y order by), y luego como las dos tablas debieran devolver lo mismo, el resultado es que ordenando por ese número de fila, obtendremos la consulta perfectamente compuesta , como puede verse en la imagen

Disfrutad el código

Descubrir bloqueos en SQL Server

Posted by Miguel Egea | Posted in Relacional | Posted on 08-01-2010

3

Los bloqueos son la principal causa de bajo rendimiento inexplicable, y generalmente son muy complicados de cazar, de detectar y de solucionar, hablaremos de bloqueos más adelante, pero ahora mismo vamos a poner un procedimiento almacenado que sirve para cazar a los procesos bloqueadores y pondremos una imagen en la que se ve cual es el resultado, en proximos capítulos pondremos como configurar el SQL Mail para que además nos lleguen por correo electrónico

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
-- ***************************************************************************
-- Copyright (C) PortalSQL 2006
--
-- Fichero: CazaBloqueadores.sql
-- Descr.: Busca bloqueos que se mantengan
-- durante el tiempo que le pasemos por parámetro, si hay bloqueos que se mantienen
-- muestra información relevante
-- autor: Miguel Egea Gómez -- Solid Quality Learning IberoAmericana
--
-- comentarios: Puede ser adecuado meter ejecutar este procedimiento desde un job y
-- usar DatabaseMail para reportar sus resultados al administrador de base
-- de datos.
-- He usado la vista de compatibilidad sys.sysprocesses, esto es porque he c
-- comprobado que algunas ocasiones la tabla sys.dm_exec_request no tiene registros
-- para los bloqueadores.
--
-- Parámetros de entrada:
-- @waittime --> Tiempo que debe esperarse para considerar que hay un bloqueo
-- Valores de retorno : 0--> Funcionó de forma correcta
-- 1--> En cualquir otro caso
--
-- <!--(más reciente más arriba) -->
-- yyyy/mm/dd by description
-- ========== ======= ==========================================================
-- 2006/06/04 MEG Creación.
--
-- ***************************************************************************
-- Ejemplo de llamada
--
/*
DECLARE @Valor varchar(10) ,@result int
SET @Valor='00:00:02'
EXEC @result =CazaBloqueadores @valor
select @result</code>
 
*/ 
 
CREATE PROC CazaBloqueadores @waittime varchar(10)
as
begin
begin try
declare @t table (bloqueado int, bloqueador int)
-- usaremos la variable de tipo tabla para esperar
insert into @t (bloqueado,bloqueador)
select session_id, blocking_session_id
from sys.dm_exec_requests der
where blocking_session_id!=0
-- Recogemos los objetos que están bloqueados..
waitfor delay @waittime
SELECT der.session_id [Sesion bloqueada],
det.text [Comando Bloqueado],
der.[blocking_Session_id] [id del bloqueador],
subq.TEXT [Comando Bloqueador],
des.[host_name] [Nombre del host],
des.[Program_name] [Aplicación],
db_name(der.database_id) [Base de Datos],
user_name(der.user_id) [usuario de bbdd],
des.login_name [login],
cast(des.context_info as varchar(100)) [Informacion Adicional],
des.cpu_time [Tiempo de CPU],
des.total_elapsed_time [Tiempo de espera],
des.logical_reads [lecturas],
des.writes [escrituras],
der.start_time [Comenzó],
der.status [estado],
case des.transaction_isolation_level
when 0 then 'Sin especificar'
when 1 then 'Read Uncommitted'
when 2 then 'Read Committed'
when 3 then 'Repeatable reads'
when 4 then 'Serializable'
when 5 then 'Snapshot'
else 'Inesperado'
end [Nivel de Aislamiento]
FROM sys.dm_exec_requests der
INNER JOIN sys.dm_exec_sessions des
ON der.session_id=des.session_id
CROSS APPLY sys.dm_exec_sql_text(sql_handle) det
left join (select SPID session_id, det2.[text]
from sys.sysprocesses der2
CROSS APPLY sys.dm_exec_sql_text(sql_handle) det2
) subq on der.[blocking_Session_id]=subq.session_id
WHERE der.blocking_session_id
in (select bloqueador from @t)
return 0
end try
begin catch
declare @error sysname
set @error=ERROR_MESSAGE()
raiserror (@error,16,1)
return 1
end catch
end 

Aquí puedes ver una imagen en la que se ejecuta un comando que genera un bloqueo, y un comando que se ve bloqueado por ese bloqueo, cuando se crea una tabla dentro de una transacción se genera un bloqueo, un select que consulte esa tabla espera a que se haga commit o rollback en la creación, para devolver los registros o un error. 

a continuación puedes ver más resultados devueltos por el procedimiento almacenado

Disfruta del código

Como reduzco mi log de transacciones

Posted by Miguel Egea | Posted in Relacional | Posted on 05-01-2010

4

Si te haces esta pregunta estás ante lo más común cuando comienzas a administrar SQL, la respuesta fácil sería darte dos comandos, y que luego funcionen o no. La verdad no me interesa eso en absoluto, creo que debes entender como funciona el log para saber porque crece, así entenderás porque aunque hagas backups todas las noches tu log sigue creciendo, y además, y mucho mejor sabrás como evitar que crezca si no tiene que hacerlo.

Para comenzar, que el log crezca depende directamente del modo de recuperación que tenga tu base de datos, solo en los modos FULL y BULK LOGGED crecerá sin medida (también puede crecer en el modo simple, es mucho más raro pero puede suceder, en 3 lineas veremos porqué).

El modo de recuperación de la bbdd puedes verlo en las propiedades (SQL Server Management Studio, te conectas al relacional, propiedades.. y en la pesstaña opciones aparece el modo de recuperación actual y en el desplegable el resto de modos. Yo tengo el cliente en inglés, así que disculpadme pero lo vereis en inglés

 

 El log de transacciones se encarga de registrar una tras otras de forma secuencial todas las modificaciones que se producen en la base de datos, esto es, la información que después ha de consolidarse en las tablas.  De esta forma el fichero MDF  (o los NDF’s ) no tienen porque contenter toda la información actualizada en un momento dado. Así pues, hagais lo que hagais NO BORREIS EL FICHERO DE LOG, que además de ser una barvaridad, os hará seguramente tener inconsistencias en la base de datos. Es más no se puede recuperar sin un comando totalmente indocumentado que usa soporte de microsoft.

Si es una estructura secuencial, y registra los cambios ¿debe crecer infinitamente?, la respuesta es depende, depende del modo de recuperación , si estamos en modo simple, en cuanto un proceso de baja prioridad que tiene SQL consolida la información del log en los datos pasa y salvaguarda los datos, esa información se puede sobre-escribir. ¿hay excepciones? SI, no se puede sobreescribir si hay una transacción antigua abierta, es decir si alguien hace, BEGIN TRAN, Update Tabla SET Campo=VAlor WHERE condicion, y se olvida de ejecutar el COMMIT TRAN o el ROLLBACK, sql no puede rehusar el trozo de log, porque no sabe que va a pasar con esa transacción y por tanto el fichero seguirá creciendo…  Si el modo de recuperación es sencillo se puede reaprovechar el log, como acabamos de ver, sin embargo, si algo falla, solo podremos recuperar el último backup completo (ningún backup del log puede garantizar que no se hallan reaprovechado trozos, y por tanto son inútiles, tanto que SQL no deja ni hacerlos :) ).

En el modo de recuperación completo y bulk logged solo se reaprovecharán estos trozos, si además de no quedar transacciones antiguas abiertas, se ha hecho copia de seguridad DEL LOG, es decir no BACKUP DATABASE sino BACKUP LOG.

Así pues ¿porque crece mi log de transacciones?,

Puede ser porque : Tienes una transacción muy antigua abierta (compruebalo con DBCC OPENTRAN en la BBDD que quieras hacer la operación), el comando devolverá algo así

Transaction information for database ‘AdventureWorks2008′.

Oldest active transaction:

SPID (server process ID): 53

UID (user ID) : -1

Name : user_transaction

LSN : (33:452:2)

Start time : Jan 5 2010 1:34:24:870AM

SID : 0×0105000000000005150000006ae2268ca3bb996b6e0e17c6e8030000

DBCC execution completed. If DBCC printed error messages, contact your system administrator.

 Si no es esto ni la hubo, puede ser porque no hayas hecho nunca copias de seguridad del log de transacciones, en cuyo caso no se reaprovecha el trocito del log.

Bueno, ya sabes porque crece, pero ya ha crecido y ahora ¿como lo reduzco?.

Bueno, el tamaño del log depende del uso de la BBDD así que no hay una regla fija, pero vamos entre el 5 y el 40% de la BBDD es “aceptable” más es muy grande, y menos es muy raro, lo normal entre el 10% y el 15%, aunque insisto, que esto no te obsesione, que no hay reglas fijas.

Si tu tamaño es demasiado grande, reducirlo puede ser una tarea sencilla, prueba los siguientes pasos :

1.- Cambia a modo de recuperación Simple

2.- Ve al menú shrink y reduce el fichero de la bbdd.

¿puede que no se reduzca ni aún así? Si, puede que no se reduzca, el log es una estructura circular y no quita espacio del principio del fichero, sino solo del final así pues lo suyo es que reorganize las páginas antes.

Con esto en principio debiera reducirse, ahora, para que no vuelva a crecer, recuerda, o bien modo de recuperación sencillo (tendrá el tamaño de la transacción abierta que más haya durado y en la que concurrentemente más cosas se hayan hecho) o bien modo completo pero con copias de seguridad frecuentes. (varias al dia es lo habitual).

Saludos