我有一个维护系统性能数据的表,每条记录都是对某个重要方法的调用,由方法名称、其持续时间和一个令牌组成——对系统的每个请求都被赋予一个唯一的令牌,所以所有的具有相同令牌的记录是相同的请求,例如:
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 服务器最终还是会进行表扫描。
其他人以前肯定有过这个问题吗?
我在这里真正需要的是按令牌分组的 SUM(Duration) 上的“索引”,即我可以在其中执行以下操作的表:
SELECT Token, SumToken FROM RequestTokens ORDER BY SumToken DESC
- 这真的是个坏主意吗?
- 如果是这样,有没有更好的方法?
- 最好的方法是什么?INSERT / UPDATE / DELETE 上的触发器会起作用(我根据旧值和更改的数据更新聚合值),还是在更新此表时手动更新我的“索引”会更好?
触发器是迄今为止我想出的最好的解决方案,但我已经看到这是一个死锁/一致性的噩梦!:-S