SQL:在核心表上聚合时忽略无关的JOIN

问题描述

假设我有桌子:

dbo.Purchases
Id | Value | UserId
1 | 10.00 | 3
2 | 1.00 | 1
3 | 15.50 | 2
4 | 13.40 | 1

dbo.Users
Id (UQ) | Name
1 | Bob
2 | Sarah
3 | Alex

还有一个视图:

dbo.PurchasesWithUsers

SELECT *
  FROM dbo.Purchases
  LEFT JOIN dbo.Users ON Users.Id = UserId

然后我将运行SELECT SUM(Value) FROM dbo.PurchasesWithUsers

现在……作为人类,我可以看到JOIN不会影响该查询

  • 它显然没有直接在SUM中使用。
  • 这是一个LEFT JOIN,因此它不能排除 Purchase行。
  • 它连接到具有UQ约束的列,因此它不能重复 Purchase行。

但是当我运行查询并查看执行计划时,引擎(MS sql Server)仍在执行JOIN,这会降低性能:(。

有什么办法可以为引擎提供更多线索,使其可以完全跳过JOIN,同时仍将VIEW用作我要查询内容 >


上下文:

  • 显然,表很大,这就是为什么性能影响如此之大
  • “表”和“视图”显然要复杂得多,但实际上并没有那么复杂-逻辑简化仍然有效,并且UQ约束是明确的(如UQ CONSTRAINTs或UQ索引)。
  • 正在使用VIEW,以便用户可以过滤各种不同的选项。 Data API处理这些选项,并将相关的WHERE子句应用于单个VIEW。 las,这意味着各种JOIN与VIEW都不相关,这取决于选择了哪些过滤器:(
  • 我知道我可以实现并直接为VIEW编制索引,但是如果可以的话,我宁愿避免这种情况,因为我可以看到一个更简单的查询计划在逻辑上已经存在。

解决方法

除非建立索引,否则视图作为数据库中存储的一组数据值不存在。数据的行和列来自定义视图的查询中引用的表,并在引用视图时动态生成。因为您不想“ 直接索引视图”,所以没有其他数据可以使用,并且服务器正在通过使用视图后面的查询来获取数据,因此无法解决避免使用此方法LEFT JOIN