2013-05-07 142 views
2

我遇到缓慢查询的问题。考虑表tblVotes - 它有两列 - VoterGuid,CandidateGuid。它拥有选民投给任何候选人的选票。非常慢的SQL查询

有超过300万行此表 - 与13000不同的选民投票时,约270万考生不同。该表中的行总数目前为650万。

什么我的查询要达到的目的是让 - 尽可能以最快和最高速高效的方式(我们使用的SQL Express) - 根据他们收到的票数排名前1000的候选人。

的代码是:

SELECT CandidateGuid, COUNT(*) CountOfVotes 
FROM dbo.tblVotes 
GROUP BY CandidateGuid 
HAVING COUNT(*) > 1 
ORDER BY CountOfVotes DESC 

...但是这需要一个scarily很长时间才能在SQL Express运行时,有一个非常完整的表。

任何人可以提出一个很好的方式来加快这得到它在快速的时间运行? CandidateGuid被单独编入索引 - 并且CandidateGuid + VoterGuid上有一个复合主键。

+0

我认为你需要CountOfVotes上的额外索引,因为你的排序是通过它来完成的,Count也会对它进行评估。 – DrCopyPaste 2013-05-07 14:30:57

+0

CountOfVotes计算在这个查询里面,它不是一个永久性的可索引列吗? – Jackfruit 2013-05-07 14:36:14

+0

哦,我的,它在这里迟到我很抱歉:) – DrCopyPaste 2013-05-07 14:38:51

回答

0

如果你有一个表只有两列,这些两个字段一个“正常”的指数不会帮助你多少,因为它实际上是整个表的副本,只订了。首先检查执行计划,如果您的索引正在使用。 然后考虑将您的索引更改为聚簇索引。

0

尝试使用,而不是having子句顶N, - 就像这样:

SELECT TOP 1000 CandidateGuid, COUNT(*) CountOfVotes 
FROM dbo.tblVotes 
GROUP BY CandidateGuid 
ORDER BY CountOfVotes DESC 
+1

详细说明,这种方式'ORDER BY'可以丢弃不在前1000的条目。实际上,最初的'HAVING'是多余的。由于这里没有加入,计数为零的候选人将不会出现在结果中。 – 2013-05-07 16:06:04

+0

引擎是否还需要为每个组计算COUNT? – 2013-05-07 16:36:17

0

我不知道如果SQL Server能够使用综合指数以加快此查询,但如果是能够这样做,您需要将查询表示为SELECT CandidateGUID, COUNT(VoterGUID) FROM . . .以获得优化。这是“安全的”,因为您知道VoterGUID从不是NULL,因为它是PRIMARY KEY的一部分。

如果您的复合主键被指定为(CandidateGUID,VoterGUID),您不会在CandidateGUID上获得单独索引的任何额外好处 - 现有索引可用于优化单例索引可帮助的任何查询