Supongamos que tengo una tabla muy larga (~ 35 millones de filas) llamada TimeCard con solo 5 columnas (tableID, CompanyID, ID de usuario, ProjectID, DailyHoursWorked, entryDate). Esta es una tabla bastante sencilla que registra las horas trabajadas de los empleados por día por proyecto por empresa.Lentitud en la vista indizada para SQL 2005
Ahora necesito generar un informe para conocer las horas trabajadas totales de los empleados por mes por proyecto para una empresa determinada. En lugar de realizar la agregación necesaria cuando se ejecuta el informe, quiero construir una estructura de datos similar a una tabla que ya tenga agregados todos los datos de la empresa/proyecto/usuario por mes, de modo que cuando se ejecute el informe, solo pueda consultar esa estructura de datos directamente sin realizar ninguna agregación en tiempo de ejecución, ya que ~ 35 millones de registros pueden tardar unos minutos.
Así que tengo 2 formas diferentes. Uno crea una tabla física adicional con (CompanyID, UserID, ProjectID, MonthlyHoursWorked, Month) como mis columnas y simplemente usa el disparador en la tabla TimeCard para modificar los valores en la tabla adicional. O puedo crear una vista indizada. Entonces intenté ambos. La primera vez que probé la vista indizada con el siguiente código:
CREATE VIEW [dbo].[vw_myView] WITH SCHEMABINDING AS
SELECT
JobID,
ProjectID,
Sum(DailyHoursWorked) AS MonthTotal,
DATEADD(Month, DATEDIFF(Month, 0, entryDate), 0) AS entryMonth,
CompanyID,
COUNT_BIG(*) AS Counter
FROM
dbo.TimeCard
Group By DATEADD(Month, DATEDIFF(Month, 0, entryDate), 0), JobID, ProjectID, CompanyID
Go
CREATE UNIQUE CLUSTERED INDEX [IX_someIndex] ON [dbo].[vw_myView]
(
[CompanyID] ASC,
[entryMonth] ASC,
[UserID] ASC,
[ProjectID] ASC
)
La vista indizada creado correcta y total con un total de ~ 5 millones de filas.
Sin embargo, cada vez que borro el caché de SQL, y ejecuto la siguiente consulta: * select * from vw_myView where companyID = 1 *, toma casi 3 minutos. Si voy con la ruta de tabla adicional como mencioné anteriormente, con mi memoria caché borrada, toma alrededor de 4 segundos.
Mis preguntas son, ¿Está indexada? ¿Ver una mala elección para este escenario en particular? En particular, me interesa saber si toda la vista indizada se vuelve a calcular/volver a agregar cada vez que se cambia la tabla subyacente (TimeCard) o cuando se ejecuta una consulta en su contra.
Gracias!
¿Qué edición de SQL Server 2005 estás usando? – RedFilter
En lugar de tener la fecha completa del primer día del mes en tu 'entryMonth', ¿no podrías tener' MONTH (entryDate) 'y posiblemente' YEAR (entryDate) 'como INTs? Me parece mucho más fácil (pero, de nuevo, no sé cuáles son sus requisitos) ... –