优化视图引用 SQL Server 中的视图的策略?

Posted

技术标签:

【中文标题】优化视图引用 SQL Server 中的视图的策略?【英文标题】:Strategies for optimizing views referencing views in SQL Server? 【发布时间】:2021-03-20 20:40:05 【问题描述】:

更新: 出于对您时间的尊重,我在子视图调用的表中添加了索引。一旦我尽可能多地改进以尽量减少复杂性并在我的帮助请求中更具体,我会回来编辑它。如果愿意,我也可以删除和重写这篇文章。


瓶颈是子视图。估计的计划显示大部分工作是表和子视图之间的哈希匹配。 link查询计划

我知道谓词和连接列应该被索引。我不确定子视图的理想策略。

我应该:

    将子视图转换为表值函数?我从专家那里听说这是一个理想的解决方案,但他们没有说明原因。我不知道子视图中的索引列是否进入主视图

    或者我是否也需要将主视图转换为表格函数以利用索引?

    或者也许我已经很远了,根本不需要转换为表值函数?

主视图:

SELECT *
FROM table1 WITH (INDEX(IX_table1))
INNER JOIN table2 WITH (INDEX(IX_table2)) ON table1.field1 = table2.field1 
                                          AND table1.field2 = table2.field2
LEFT JOIN SubView WITH (nolock) ON table1.field1 = SubView1.field1
                                AND table1.field2 = SubView1.field2
                                AND table2.field3 = SubView1.field3
                                AND table2.field4 = SubView1.field4
WHERE table1.PredicateDate >= dynamicDate
  AND table1.field1 IN (3, 4)
  AND table1.field5 = 0

【问题讨论】:

只是一个观察 - 在视图中嵌入 nolocks 和索引提示是一个非常糟糕的主意。当有人删除该索引时会发生什么?迟早,他们会,他们总是这样做。大概您正在尝试绕过优化器来构建最佳计划! 由于不知道性能问题到底是什么,您已经走得太远了。 TVF 可能会加快它的速度(除非涉及窗口函数,否则不太可能)。您真正需要的是 edit 并添加您的表 和索引 定义,SubView 的定义,通过 brentozar.com/pastetheplan 共享查询计划,并说明:dynamicDate 如何进入查询(变量、参数、动态 SQL),为什么选择强制使用这些索引和nolock。如果没有这些信息,我们将无能为力,因为我们不知道问题可能出在哪里,也不知道您采取了哪些措施来解决它。 谢谢@Charlieface。 brentozar.com/pastetheplan/?id=r11_Se44d 在没有 WITH 提示的情况下,视图没有使用索引。动态日期是一个计算变量。至于 NOLOCK,我没有很好的理由,除了我继承的每个代码都有它而且没有人审查我的代码批评,所以我认为这是标准做法。 这是一个与上面的查询完全不同的查询。您的索引显然留下了改进的空间。 请edit您的问题并添加我要求的所有信息,以及完整的查询,最好是实际计划而不是估计 计划,那太好了 SSMS,当您显示实际执行计划时,将推荐您可以创建的索引以帮助您的查询运行得更快。右键单击查询文本框并选择“显示实际执行计划”,然后运行您的查询。而且,如果您read this 并向我们提供更多信息,我们可以为您提供更好的帮助。请edit您的问题。 【参考方案1】:

抱歉。 . .放在答案部分而不是评论部分。但是在尝试修复之后,这并不重要。 . .没有足够的帖子来添加评论。

这适用于 Microsoft ERP 系统上的表格。 Microsoft 在不应更改或删除的表上具有默认索引。无论如何,在任何 ERP 升级中,索引都会由 Microsoft 重新创建。

大多数报告的表格是订单历史记录标题(800 万条记录)和行(5700 万条记录)。当订单转移到发票或过帐发票时,这些表会被填充。对于第一种情况,订单转到历史表,并在打开的表中创建发票。第二种情况,发票过帐时将发票移至历史记录表。对于这些流程,ERP 系统有一个胖客户端(自 2010 年或更早以来没有太大变化)。该过程是一个相当长的过程,其中包含许多不使用显式 SQL 事务的表。如果此过程中断,则需要手动修复任何未更新的表。

READONLY/READUNCOMMITTED 最初用于针对实时数据库进行大型报告。 Vinh 正在使用的 Views 用于现在就位的复制服务器。 READONLY 通常用于针对前几个月/几天的信息,因此当前日期的更改不是问题。大型报告正在减慢上一段中讨论的传输和发布过程。上面的过帐过程目前大约需要 1 小时才能过帐 500 笔交易,因此我们可以随时保持过程不会变慢。

为什么要指定特定索引:5700 万行分为订单类型(SOPTYPE 2(订单)、3(发票)和 5(延期交货))。大多数 Microsoft 索引使用 SOPTYPE 作为索引中的第一个字段。所以大多数查询最终使用索引扫描而不是索引搜索。在某些情况下,只需指定索引即可将查询时间从 2 分钟缩短到 5 秒。在比较索引分数时,两个索引可能都在 80%,但 SQL 倾向于选择 SOPTYPE 作为第一个索引字段的索引。

我们可能是特定 ERP 系统的较大数据用户之一。我不相信微软已经针对这种数据大小进行了优化。

我希望这些信息对您有所帮助。

【讨论】:

【参考方案2】:

由于我无法控制的依赖关系,优化子视图需要一段时间。无法删除帖子,因此暂时关闭此问题。

【讨论】:

以上是关于优化视图引用 SQL Server 中的视图的策略?的主要内容,如果未能解决你的问题,请参考以下文章

有关 SQL Server 中的 SQL 查询提示的详细信息

SQL Server 2005 嵌套视图 - 解除纠缠的策略? [关闭]

SQL Server 视图何时更新?

使用奇怪的查询优化器行为加入 SQL Server 中的视图

Sql Server 视图可以引用不同数据库中的表吗?

Sql Server系列:视图