问题描述
假设我有桌子:
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
。