【发布时间】:2010-11-30 02:03:58
【问题描述】:
我有一个维护系统性能数据的表,每条记录都是对某个重要方法的调用,由方法名称、其持续时间和一个令牌组成——对系统的每个请求都被赋予一个唯一的令牌等所有具有相同token的记录都是同一个请求,例如:
CallName Duration Token
----------- ----------- -----------
GetData 121 12345
Process 800 12345
SaveData 87 12345
GetData 97 ABCDE
Process 652 ABCDE
SaveData 101 ABCDE
我对按 Token 和 CallName 分组的聚合数据感兴趣,例如:
-- The total duration of each request, in descending order
SELECT Token, SUM(Duration) FROM Requests GROUP BY Token ORDER BY SUM(Duration) DESC
-- The average duration of each call, in descending order
SELECT CallName, AVG(Duration) FROM Requests GROUP BY CallName ORDER BY AVG(Duration) DESC
现在这个表可能非常大,我只会对每个查询的前几条记录感兴趣,因此我已经为这两个查询实现了分页。问题在于,因为这些查询涉及聚合函数,SQL 服务器最终还是会进行表扫描。
肯定其他人以前也遇到过这个问题吗?
我在这里真正需要的是按 Token 分组的 SUM(Duration) 上的“索引”,即我可以在其中执行以下操作的表:
SELECT Token, SumToken FROM RequestTokens ORDER BY SumToken DESC
- 这真的是个坏主意吗?
- 如果是这样,有没有更好的方法?
- 最好的方法是什么? INSERT / UPDATE / DELETE 上的触发器会起作用(我根据旧值和更改的数据更新聚合值),还是在更新此表时手动更新我的“索引”会更好?
到目前为止,触发器是我想出的最佳解决方案,但我已经看到这是一场僵局/一致性的噩梦! :-S
【问题讨论】:
-
索引视图在某些情况下很有帮助。
-
我想知道,但是索引视图不允许使用大多数(可能是所有)聚合函数(MAX、AVG 等...) - sqlteam.com/article/indexed-views-in-sql-server-2000
标签: sql-server-2005 group-by aggregate-functions