日期:2014-05-17  浏览次数:20624 次

group by sum 优化
DBCC FREEPROCCACHE
DBCC DROPCLEANBUFFERS
set statistics io on
SET STATISTICS time ON

SELECT
  top 10
  [UserID]
  , sum([Score]) score
FROM 
  [users]  
group by 
  UserID
order by 
  Score desc

500w数据.
userid, 非聚焦索引
score 非聚焦索引

时间11秒.
测试电脑配置 amd640(3.0); 8G内存;

------解决方案--------------------
SQL code

-->try
select t.[UserID],sum(t.[Score]) Score
from
(
    SELECT top 10 [UserID],[Score]
    FROM [users]   
    group by UserID
    order by Score desc
) t

------解决方案--------------------
不好意思,上面那个写的有问题
------解决方案--------------------
这还可以再优化?
------解决方案--------------------
SQL code

-->try 
SELECT top 10 [UserID] into #tmp 
FROM [users] group by UserID

select [UserID], sum([Score]) Score from [users]
where [UserID] in (select t.[UserID] from #tmp t)
order by Score desc

--drop table #tmp

------解决方案--------------------
发一下生成表结构的脚本看看
------解决方案--------------------
探讨
引用:

SQL code

-->try
SELECT top 10 [UserID] into #tmp
FROM [users] group by UserID

select [UserID], sum([Score]) Score from [users]
where [UserID] in (select t.[UserID] from #tmp t)……

------解决方案--------------------
SQL code
SELECT TOP 10
        [UserID] ,
        SUM([Score]) score
FROM    [users]
GROUP BY UserID
ORDER BY Score DESC

------解决方案--------------------
userid, 非聚焦索引
score 非聚焦索引 

把这个改成 userid和score 的联合索引试试。
------解决方案--------------------
探讨
score 非聚焦索引

------解决方案--------------------
最好的索引应该是:
SQL code
CREATE INDEX IXC_Userid_Score ON users (Userid) INCLUDE (Score)

------解决方案--------------------
探讨

最好的索引应该是:
SQL code
CREATE INDEX IXC_Userid_Score ON users (Userid) INCLUDE (Score)


最快的方式应该算是索引视图:SQL code

SET NUMERIC_ROUNDABORT OFF;
SET ANSI_PADDING, ANSI_WARNINGS, CONCAT_NULL_YIELDS_NULL,……

------解决方案--------------------
Score 总是需要sum,然后再对sum排序,所以score只要出现在索引的叶子层就足够了。
------解决方案--------------------
22楼的最正确,索引的话,score在选择上面没用就不必要包括在索引列中了,会增加索引的大小。不过跟23楼的差不了多少的。
------解决方案--------------------
探讨

Score 总是需要sum,然后再对sum排序,所以score只要出现在索引的叶子层就足够了。

------解决方案--------------------
25楼你说的不错,差不多,就看索引的级别有多少了。
------解决方案--------------------
探讨
最好的索引应该是:

SQL code
CREATE INDEX IXC_Userid_Score ON users (Userid) INCLUDE (Score)


最快的方式应该算是索引视图:

SQL code

SET NUMERIC_ROUNDABORT OFF;
SET ANSI_PADDING, ANSI_WARNINGS, CONCAT_NULL_YIEL……