【发布时间】:2019-01-23 15:17:27
【问题描述】:
我已经定义了一个视图,其中列出了交易以及运行总计,类似于
CREATE VIEW historyView AS
SELECT
a.createdDate,
a.value,
m.memberId,
SUM(a.value) OVER (ORDER BY a.createdDate) as runningTotal,
...many more columns...
FROM allocations a
JOIN member m ON m.id = a.memberId
JOIN ...many joins...
此查询查看的最大表有大约 1000 万行,但平均而言,当查询视图时,它只会返回几十行。
我的问题是,当这个SELECT 语句直接为给定成员运行时,它执行得非常快,并在几毫秒内返回结果。但是,当作为视图查询时...
SELECT h.createdDate, h.value, h.runningTotal
FROM historyView h
WHERE member.username = 'blah@blah.com'
...表现很糟糕。这两个查询计划非常不同——在第一种情况下它非常理想,但在后一种情况下,有大量的扫描和数十万/数百万行被读取。这显然是因为对成员的过滤器是在完成其他所有操作之后运行的最后一件事,而不是一开始就在前面运行。
如果我删除SUM(x) OVER (ORDER BY y) 子句,这个问题就会消失。
我可以做些什么来确保SUM(x) OVER (ORDER BY y) 子句不会破坏查询计划?
【问题讨论】:
-
这就是优化视图的方式。这是一种耻辱。使用内联表值函数可能会更好。
-
太可惜了!不幸的是,针对这个视图的查询是由一些 OData 中间件生成的,这些中间件将对各种事情进行过滤,所以我不确定 TVF 是否可以工作
-
欢迎使用 SQL。
标签: sql view sum sql-server-2016 window-functions