假设我有一个很长的表(约 3500 万行),名为 TimeCard,只有 5 列(tableID、CompanyID、UserID、ProjectID、DailyHoursWorked、entryDate)。这是一个非常简单的表格,记录了每个公司每个项目每天的员工工作时间。
我现在需要生成一份报告,以找出任何给定公司每个项目每月员工的总工作时间。我不想在报表运行时执行所需的聚合,而是想构建一个类似表格的数据结构,其中已经包含按月聚合的所有公司/项目/用户数据,因此当报表运行时,我可以直接查询该数据结构无需执行任何运行时聚合,因为大约 3500 万条记录可能需要几分钟。
所以我有两种不同的方式。一个人创建了一个额外的物理表,其中 (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
)
正确创建的索引视图总共有大约 500 万行。
但是,每次如果我清除 SQL 缓存并运行以下查询:*select * from vw_myView where companyID = 1*,则需要将近 3 分钟。如果我使用上面提到的额外表路由,清除缓存,大约需要 4 秒。
我的问题是,索引视图对于这种特定情况是一个糟糕的选择吗?特别是我很想知道每次更改基础表(TimeCard)或针对它运行查询时是否重新计算/重新聚合整个索引视图?
谢谢!