【问题标题】:Very slow SQL query非常慢的 SQL 查询
【发布时间】:2013-05-07 14:27:32
【问题描述】:

我遇到了查询缓慢的问题。考虑表 tblVotes - 它有两列 - VoterGuid, CandidateGuid。它持有选民投票给任意数量的候选人的票。

此表中有超过 300 万行 - 大约 13,000 名不同的选民投票给大约 270 万不同的候选人。表中的总行数目前为 650 万。

我的查询试图以最快和最高效的缓存方式(我们正在使用 SQL Express)获得 - 根据他们收到的票数排名前 1000 位候选人。

代码是:

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

...但是当有一个非常满的表时,这需要很长时间才能在 SQL express 上运行。

任何人都可以提出一个好方法来加速它并让它快速运行吗? CandidateGuid 是单独索引的 - CandidateGuid+VoterGuid 上有一个复合主键。

【问题讨论】:

  • 我认为您需要在 CountOfVotes 上建立一个额外的索引,因为您的排序已经完成,并且 count 也会对其进行评估。
  • CountOfVotes 是在这个查询中计算出来的,它不是一个永久的可索引列吗?
  • 天哪,来晚了我很抱歉 :)
  • 是的,这是个糟糕的建议,但实际上可能有用的是索引视图,这样你就可以用内存来获得更快的速度,这是一个示例问题:stackoverflow.com/questions/6030143/count-big-in-indexed-view
  • 听起来很有趣,但这里的内存非常宝贵,因为它是 SQL Express(有限制)..

标签: sql sql-server performance sql-server-express


【解决方案1】:

如果您的表中只有两列,那么这两个字段上的“正常”索引对您没有多大帮助,因为它实际上是整个表的副本,只是有序的。首先检查执行计划,如果您的索引正在被使用。 然后考虑将您的索引更改为聚集索引。

【讨论】:

    【解决方案2】:

    尝试使用 top n,而不是 having 子句 - 像这样:

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

    【讨论】:

    • 详细来说,这样ORDER BY可以丢弃不在前1000名的条目。其实原来的HAVING是多余的。由于此处没有连接,因此计数为零的候选人将不会出现在结果中。
    • 引擎是否还需要计算每个 GROUP 的 COUNT?
    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-16
      • 1970-01-01
      • 1970-01-01
      • 2021-12-18
      • 1970-01-01
      • 2020-01-10
      相关资源
      最近更新 更多