我有一个记录表,我需要在其上运行接近实时的报告。主键是非顺序插入的 guid。当添加其他索引以帮助提高报告速度时,我看到插入超时。我计划创建一个带有报告索引的重复表,并在日志表中只保留填充因子为 75% 的聚集索引。
我觉得只对一张表使用复制就有点过分了。所以我的问题是我应该如何做到这一点?我应该安排一个 sql 代理作业吗?
任何帮助都会很棒!谢谢!
我有一个记录表,我需要在其上运行接近实时的报告。主键是非顺序插入的 guid。当添加其他索引以帮助提高报告速度时,我看到插入超时。我计划创建一个带有报告索引的重复表,并在日志表中只保留填充因子为 75% 的聚集索引。
我觉得只对一张表使用复制就有点过分了。所以我的问题是我应该如何做到这一点?我应该安排一个 sql 代理作业吗?
任何帮助都会很棒!谢谢!
您有很多选择。为了解决您当前的问题,我会确保日志记录表上有一个顺序 ID,并且只将新数据复制到索引良好的报告表中。然后,您可以运行非锁定过程以仅获取报告中相应列的最大值,并从日志记录表中获取更大的值。
DECLARE @MaxValue uniqueidentifier
SELECT @MaxValue = MAX(LogID) FROM LogTable
INSERT INTO
ReportingTable
(...)
SELECT
...
FROM
LogTable WITH NOLOCK
WHERE
LogID > @MaxValue
注意:请参阅此进行NOLOCK辩论。仅当您的日志表很大且很忙时才使用它,但您的场景是它有意义的一个示例。
我不确定是什么生成了您的 GUID,但如果它是 SQL 服务器,那么将列默认为NEWSEQUENTIALID()意味着它不是完全随机的,而是顺序的。如果您从其他地方获取 GUID,则考虑放置一个bigint IDENTITY(1,1)列以确保您的聚集索引没有严重碎片化。碎片聚集索引很糟糕,因为您的其他索引使用它进行查找,所以无论它们多么好,它们仍然会比主索引运行得慢。
然后,您可以使用 GUID 上的聚集索引以任何您喜欢的方式构建报告表,并且仅使用索引良好的表中的最大值来仅插入您还没有的新数据。您还可以在该表上运行重新索引以确保它尽可能快。
更多信息..
如果您希望您的系统增长很多,那么您应该查看其他一些报告模式,以便在将数据转储到报告表中时对数据进行非规范化或简化。
看一下星形模式,或者您可以将每日或每周的统计数据非规范化到一个单独的表格中,如下所示:
Date, TimespentTotal, TimespentAvg, UserFact2Count....
然后您可以运行一个非锁定存储过程来一次获取一天的统计信息。我还建议根据您在报告数据库中没有的内容加载天数统计信息,以防运行它的代理作业失败,它将在下一次运行时处理积压。显然,这些模式需要做更多的工作,而且错误的选择可能会很糟糕,因此只有在需要并知道对报告的期望时才做出此选择。