Допустим, у меня есть очень длинная таблица (~ 35 миллионов строк), которая называется TimeCard и имеет всего 5 столбцов (tableID, CompanyID, UserID, ProjectID, DailyHoursWorked, entryDate). Это довольно простая таблица, в которой записываются рабочие часы сотрудников в день на проект для каждой компании.
Теперь мне нужно сгенерировать отчет, чтобы узнать общее количество рабочих часов сотрудников в месяц на проект для любой конкретной компании. Вместо того чтобы выполнять агрегацию, необходимую при выполнении отчета, я хочу создать табличную структуру данных, в которой уже собраны все данные о компании / проекте / пользователе, сгруппированные по месяцам, поэтому при выполнении отчета я могу просто запросить эту структуру данных напрямую без выполнения агрегации во время выполнения, поскольку ~ 35 миллионов записей могут занять несколько минут.
Так что у меня есть 2 разных способа. Создайте дополнительную физическую таблицу с (CompanyID, UserID, ProjectID, MonthlyHoursWorked, Month) в качестве моих столбцов и просто используйте триггер в таблице TimeCard для изменения значений в дополнительной таблице. Или я могу создать индексированное представление. Поэтому я попробовал оба. Сначала я попробовал индексированное представление с помощью следующего кода:
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
)
Индексированное представление создано правильно и содержит в общей сложности ~ 5 миллионов строк.
Однако каждый раз, когда я очищаю кэш SQL и выполняю следующий запрос: * select * from vw_myView, где companyID = 1 *, это занимает почти 3 минуты. Если я выберу дополнительный маршрут таблицы, как я уже упоминал выше, с очищенным кэшем, это займет около 4 секунд.
Мои вопросы: является ли индексированный просмотр плохим выбором для данного конкретного сценария? В частности, мне интересно знать, будет ли пересчитываться / агрегироваться все индексированное представление каждый раз, когда базовая таблица (TimeCard) изменяется или когда к ней выполняется запрос?
Спасибо!