需要改进视图性能的建议

JHF*_*HFB 6 performance sql-server-2008 database-design sql-server view query-performance

我希望提高 SQL Server 2008 中视图的性能。这个视图存在于一个报告数据库中,非技术人员广泛使用该数据库来基本上对一个人的所有这些属性进行非规范化。

这是一个非常复杂的长期运行视图。我们有超过 1900 万人,每一列都有很多逻辑。例如,有一个关于一个人是否已故的指标,它依赖于三个 CTE(公共表表达式)和一个 case 语句。

基本上,这是一场噩梦。

我需要想办法提高性能。无法将其更改为表格 - 数据必须准确无误。将其更改为索引视图是正确的 - 它使用来自多个数据库的数据。我无法真正修改列结构,因为它会破坏许多现有报告。

工具箱中是否有可能有帮助的工具?我想知道存储过程或函数是否有帮助。也许是一个带有计算列的表?我将能够每晚提取此人的识别信息并将其存储到表格中,但绝大多数列依赖于实时数据。

Aar*_*and 6

视图通常不是为了性能而实现的。虽然您目前无法实现显式索引视图(这只是 SQL Server 为您维护的视图),但您当然可以自己手动维护事实。

例如,您提到您目前使用三个 CTE 和一个 CASE 表达式来计算“某人是否死了”(抱歉,迂腐,这不是一个陈述)。

与其在每次访问视图时都引用这组 CTE,为什么不将该事实放在一个表中(可能与每个用户必须计算的其他事实一起),并在后台定期计算?因此,也许每 5 分钟(这只是一个 SWAG,您必须确定什么是合适的),您运行一个 SQL Server 代理作业,根据它当前知道的事实重新填充表。现在视图只需要引用作为该脚本输出的表,而不是在用户等待时一遍又一遍地计算它。例如:

CREATE TABLE dbo.PersonProperties
(
  PersonID INT PRIMARY KEY REFERENCES dbo.Persons(PersonID),
  IsDead BIT NOT NULL DEFAULT 0
);
Run Code Online (Sandbox Code Playgroud)

现在,该作业可以简单地将该表与 CTE 的结果合并,然后视图可以包含对该表的引用,该表可以简单地将 BIT 列与 PK 上的连接一起拉出。这在查询时应该便宜得多,每次都重新评估所有这些逻辑。

为了最大限度地减少阻塞(例如,当用户在作业运行的同时访问视图时),您可以实现我所说的“schema switch-a-roo”,我在这里写了博客:

http://www.sqlperformance.com/2012/08/t-sql-queries/t-sql-tuesday-schema-switch-a-roo

因此,不是在整个操作过程中在昂贵的查询上锁定资源,而是发生的唯一阻塞是元数据切换实际发生时。


只要您能承受一些数据不准确的短暂时期,这种方法就有效。您可以收紧该窗口以使其非常窄,但总有一个人可能会在这两者之间死亡,并且在短时间内询问会返回他们还活着的信息。如果您负担不起,那么您可以将其作为首先将该事实引入数据库的流程的一部分,以确保 CTE 立即反映这一点,并且新表也立即反映这一点。

还是不够好?将用户标记为“脏”,然后为他们进行更改。视图可以与“干净”用户的陈旧数据联合或左连接,并仅跟踪“脏”用户的实时数据。